diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e57f68a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.json] +indent_size = 2 + +[*.md] +max_line_length = off +trim_trailing_whitespace = false + +[*.{yaml,yml}] +indent_size = 2 diff --git a/.eslintrc.yaml b/.eslintrc.yaml new file mode 100644 index 0000000..20a2fd6 --- /dev/null +++ b/.eslintrc.yaml @@ -0,0 +1,75 @@ +--- + +env: + es6: true + node: true + +overrides: + - + files: + - '*.js' + extends: + - '@matthiaskunnen/eslint-config-base' + + - + env: + jasmine: true + files: + - 'spec/**/*.ts' + extends: + - '@matthiaskunnen/eslint-config-typescript' + + parser: '@typescript-eslint/parser' + + parserOptions: + project: + - tsconfig/tsconfig.lint.json + sourceType: module + + plugins: + - jasmine + + rules: + '@typescript-eslint/no-use-before-define': off + func-names: off + jasmine/expect-matcher: error + jasmine/expect-single-argument: error + jasmine/missing-expect: error + jasmine/named-spy: off # We might consider this + jasmine/no-assign-spyon: error + jasmine/no-describe-variables: error + jasmine/no-disabled-tests: error + jasmine/no-expect-in-setup-teardown: error + jasmine/no-focused-tests: error + jasmine/no-global-setup: error + jasmine/no-pending-tests: warn + jasmine/no-promise-without-done-fail: error + jasmine/no-spec-dupes: + - error + - branch + jasmine/no-suite-callback-args: error + jasmine/no-suite-dupes: error + jasmine/no-unsafe-spy: error + jasmine/prefer-jasmine-matcher: error + + - + files: + - 'src/**/*.ts' + extends: + - '@matthiaskunnen/eslint-config-typescript' + + parser: '@typescript-eslint/parser' + + parserOptions: + project: + - tsconfig/tsconfig.lint.json + sourceType: module + rules: + '@typescript-eslint/no-use-before-define': + - error + - + classes: true + enums: true + functions: false + variables: true + typedefs: true diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 6318898..ca76b45 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -1,6 +1,6 @@ name: Node CI -on: [push] +on: [pull_request, push] jobs: build: @@ -9,7 +9,7 @@ jobs: strategy: matrix: - node-version: [8.x, 10.x, 12.x] + node-version: [10.x, 12.x, 14.x] steps: - uses: actions/checkout@v1 @@ -17,10 +17,13 @@ jobs: uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - - name: npm install, build, and test + - name: yarn install, lint, build, and test run: | - npm ci - npm run build --if-present - npm test + yarn install --frozen-lockfile + yarn run lint + yarn run build + yarn run coverage + yarn run test:ts + yarn run size env: CI: true diff --git a/.github/workflows/size.yml b/.github/workflows/size.yml new file mode 100644 index 0000000..d45c639 --- /dev/null +++ b/.github/workflows/size.yml @@ -0,0 +1,21 @@ +name: "size" + +on: [pull_request] + +jobs: + size: + runs-on: ubuntu-latest + env: + CI_JOB_NUMBER: 1 + steps: + - uses: actions/checkout@v1 + - + name: yarn install + run: | + yarn install --frozen-lockfile + env: + CI: true + - uses: andresz1/size-limit-action@v1.4.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + skip_step: install diff --git a/.gitignore b/.gitignore index 33595a7..c7e3aa3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,11 +2,13 @@ bin node_modules packages coverage +/lib nuget nupkg obj Properties temp +.eslintcache .idea .nyc_output *.cs @@ -26,4 +28,3 @@ temp **\nuget **\nupkg __* - diff --git a/.npmignore b/.npmignore deleted file mode 100644 index cca1243..0000000 --- a/.npmignore +++ /dev/null @@ -1,12 +0,0 @@ -src/ -src_v0/ -spec/ -package-lock.json -tsconfig.json -webpack.config.js -.idea/ -.vscode/ -.gitattributes -.travis.yml -*.iml - diff --git a/js/parser.d.ts b/js/parser.d.ts deleted file mode 100644 index c60345a..0000000 --- a/js/parser.d.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { Constructor } from "./typedjson/types"; -import { TypeHintEmitter } from "./typedjson/serializer"; -import { TypeResolver } from "./typedjson/deserializer"; -import { OptionsBase } from "./typedjson/options-base"; -export declare type JsonTypes = Object | boolean | string | number | null | undefined; -export { TypeResolver, TypeHintEmitter }; -export interface ITypedJSONSettings extends OptionsBase { - /** - * 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?: TypeResolver; - 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?: TypeHintEmitter; - /** - * 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): Object[] | undefined; - static toPlainMap(object: Map, keyCtor: Constructor, valueCtor: Constructor, settings?: ITypedJSONSettings): { - key: any; - value: any; - }[] | undefined; - 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 deleted file mode 100644 index 307ab6b..0000000 --- a/js/typedjson.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { TypedJSON, ITypedJSONSettings, JsonTypes, TypeResolver, TypeHintEmitter } from "./parser"; -export { jsonObject } from "./typedjson/json-object"; -export { jsonMember } from "./typedjson/json-member"; -export { jsonArrayMember } from "./typedjson/json-array-member"; -export { jsonSetMember } from "./typedjson/json-set-member"; -export { jsonMapMember } from "./typedjson/json-map-member"; -export { toJson } from "./typedjson/to-json"; diff --git a/js/typedjson.js b/js/typedjson.js deleted file mode 100644 index 63e85f1..0000000 --- a/js/typedjson.js +++ /dev/null @@ -1,1754 +0,0 @@ -// [typedjson] Version: 1.5.1 - 2020-02-09 - (function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define("typedjson", [], factory); - else if(typeof exports === 'object') - exports["typedjson"] = factory(); - else - root["typedjson"] = factory(); -})((typeof self !== 'undefined' ? self : this), function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); - -// CONCATENATED MODULE: ./src/typedjson/helpers.ts -var __spreadArrays = (undefined && undefined.__spreadArrays) || function () { - for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; - for (var r = Array(s), k = 0, i = 0; i < il; i++) - for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) - r[k] = a[j]; - return r; -}; -var METADATA_FIELD_KEY = "__typedJsonJsonObjectMetadataInformation__"; -var MISSING_REFLECT_CONF_MSG = 'Are you sure, that you have both "experimentalDecorators"' + - ' and "emitDecoratorMetadata" in your tsconfig.json?'; -function getDefaultValue(type) { - switch (type) { - case Number: - return 0; - case String: - return ""; - case Boolean: - return false; - case Array: - return []; - default: - return undefined; - } -} -/** - * Determines whether the specified type is a type that can be passed on "as-is" into `JSON.stringify`. - * Values of these types don't need special conversion. - * @param type The constructor of the type (wrapper constructor for primitive types, e.g. `Number` for `number`). - */ -function isDirectlySerializableNativeType(type) { - return !!(~[Date, Number, String, Boolean].indexOf(type)); -} -function isDirectlyDeserializableNativeType(type) { - return !!(~[Number, String, Boolean].indexOf(type)); -} -function isTypeTypedArray(type) { - return !!(~[Float32Array, Float64Array, Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array] - .indexOf(type)); -} -function isPrimitiveValue(obj) { - switch (typeof obj) { - case "string": - case "number": - case "boolean": - return true; - default: - return (obj instanceof String || obj instanceof Number || obj instanceof Boolean); - } -} -function isObject(value) { - return typeof value === "object"; -} -function shouldOmitParseString(jsonStr, expectedType) { - var expectsTypesSerializedAsStrings = expectedType === String - || expectedType === ArrayBuffer - || expectedType === DataView; - var hasQuotes = jsonStr.length >= 2 && jsonStr[0] === '"' && jsonStr[jsonStr.length - 1] === '"'; - var isInteger = /^\d+$/.test(jsonStr.trim()); - return (expectsTypesSerializedAsStrings && !hasQuotes) || ((!hasQuotes && !isInteger) && expectedType === Date); -} -function parseToJSObject(json, expectedType) { - if (typeof json !== 'string' || shouldOmitParseString(json, expectedType)) { - return json; - } - return JSON.parse(json); -} -/** - * Determines if 'A' is a sub-type of 'B' (or if 'A' equals 'B'). - * @param A The supposed derived type. - * @param B The supposed base type. - */ -function isSubtypeOf(A, B) { - return A === B || A.prototype instanceof B; -} -function logError(message) { - var optionalParams = []; - for (var _i = 1; _i < arguments.length; _i++) { - optionalParams[_i - 1] = arguments[_i]; - } - if (typeof console === "object" && typeof console.error === "function") { - console.error.apply(console, __spreadArrays([message], optionalParams)); - } - else if (typeof console === "object" && typeof console.log === "function") { - console.log.apply(console, __spreadArrays(["ERROR: " + message], optionalParams)); - } -} -function logMessage(message) { - var optionalParams = []; - for (var _i = 1; _i < arguments.length; _i++) { - optionalParams[_i - 1] = arguments[_i]; - } - if (typeof console === "object" && typeof console.log === "function") { - console.log.apply(console, __spreadArrays([message], optionalParams)); - } -} -function logWarning(message) { - var optionalParams = []; - for (var _i = 1; _i < arguments.length; _i++) { - optionalParams[_i - 1] = arguments[_i]; - } - if (typeof console === "object" && typeof console.warn === "function") { - console.warn.apply(console, __spreadArrays([message], optionalParams)); - } - else if (typeof console === "object" && typeof console.log === "function") { - console.log.apply(console, __spreadArrays(["WARNING: " + message], optionalParams)); - } -} -/** - * Checks if the value is considered defined (not undefined and not null). - * @param value - */ -function isValueDefined(value) { - return !(typeof value === "undefined" || value === null); -} -function isInstanceOf(value, constructor) { - if (typeof value === "number") { - return (constructor === Number); - } - else if (typeof value === "string") { - return (constructor === String); - } - else if (typeof value === "boolean") { - return (constructor === Boolean); - } - else if (isObject(value)) { - return (value instanceof constructor); - } - return false; -} -var isReflectMetadataSupported = (typeof Reflect === "object" && typeof Reflect.getMetadata === "function"); -/** - * Gets the name of a function. - * @param fn The function whose name to get. - */ -function nameof(fn) { - if (typeof fn.name === "string") { - return fn.name; - } - return "undefined"; -} - -// CONCATENATED MODULE: ./src/typedjson/metadata.ts - -var metadata_JsonObjectMetadata = /** @class */ (function () { - //#endregion - function JsonObjectMetadata(classType) { - this.dataMembers = new Map(); - this.knownTypes = new Set(); - /** - * Indicates whether this class was explicitly annotated with @jsonObject - * or implicitly by @jsonMember - */ - this.isExplicitlyMarked = false; - /** - * Indicates whether this type is handled without annotation. This is usually - * used for the builtin types (except for Maps, Sets, and normal Arrays). - */ - this.isHandledWithoutAnnotation = false; - this.classType = classType; - } - //#region Static - /** - * Gets the name of a class as it appears in a serialized JSON string. - * @param ctor The constructor of a class (with or without jsonObject). - */ - JsonObjectMetadata.getJsonObjectName = function (ctor) { - var metadata = JsonObjectMetadata.getFromConstructor(ctor); - return metadata ? nameof(metadata.classType) : nameof(ctor); - }; - /** - * Gets jsonObject metadata information from a class. - * @param ctor The constructor class. - */ - JsonObjectMetadata.getFromConstructor = function (ctor) { - var prototype = ctor.prototype; - if (!prototype) { - return; - } - var metadata; - if (prototype.hasOwnProperty(METADATA_FIELD_KEY)) { - // The class prototype contains own jsonObject metadata - metadata = prototype[METADATA_FIELD_KEY]; - } - // Ignore implicitly added jsonObject (through jsonMember) - if (metadata && metadata.isExplicitlyMarked) { - return metadata; - } - // In the end maybe it is something which we can handle directly - if (JsonObjectMetadata.doesHandleWithoutAnnotation(ctor)) { - var primitiveMeta = new JsonObjectMetadata(ctor); - primitiveMeta.isExplicitlyMarked = true; - // we do not store the metadata here to not modify builtin prototype - return primitiveMeta; - } - }; - /** - * Gets the known type name of a jsonObject class for type hint. - * @param constructor The constructor class. - */ - JsonObjectMetadata.getKnownTypeNameFromType = function (constructor) { - var metadata = JsonObjectMetadata.getFromConstructor(constructor); - return metadata ? nameof(metadata.classType) : nameof(constructor); - }; - JsonObjectMetadata.doesHandleWithoutAnnotation = function (ctor) { - return isDirectlySerializableNativeType(ctor) || isTypeTypedArray(ctor) - || ctor === DataView || ctor === ArrayBuffer; - }; - return JsonObjectMetadata; -}()); - -function injectMetadataInformation(constructor, propKey, metadata) { - var decoratorName = "@jsonMember on " + nameof(constructor.constructor) + "." + String(propKey); // For error messages. - var objectMetadata; - // When a property decorator is applied to a static member, 'constructor' is a constructor function. - // See: https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md#property-decorators - // ... and static members are not supported here, so abort. - if (typeof constructor === "function") { - logError(decoratorName + ": cannot use a static property."); - return; - } - // Methods cannot be serialized. - // @ts-ignore symbol indexing is not supported by ts - if (typeof constructor[propKey] === "function") { - logError(decoratorName + ": cannot use a method property."); - return; - } - if (!metadata || (!metadata.ctor && !metadata.deserializer)) { - logError(decoratorName + ": JsonMemberMetadata has unknown ctor."); - return; - } - // Add jsonObject metadata to 'constructor' if not yet exists ('constructor' is the prototype). - // NOTE: this will not fire up custom serialization, as 'constructor' must be explicitly marked with '@jsonObject' as well. - if (!constructor.hasOwnProperty(METADATA_FIELD_KEY)) { - // No *own* metadata, create new. - objectMetadata = new metadata_JsonObjectMetadata(constructor.constructor); - // Inherit @JsonMembers from parent @jsonObject (if any). - var parentMetadata = constructor[METADATA_FIELD_KEY]; - if (parentMetadata) // && !constructor.hasOwnProperty(Helpers.METADATA_FIELD_KEY) - { - parentMetadata.dataMembers.forEach(function (_metadata, _propKey) { return objectMetadata.dataMembers.set(_propKey, _metadata); }); - } - // ('constructor' is the prototype of the involved class, metadata information is added to this class prototype). - Object.defineProperty(constructor, METADATA_FIELD_KEY, { - enumerable: false, - configurable: false, - writable: false, - value: objectMetadata - }); - } - else { - // JsonObjectMetadata already exists on 'constructor'. - objectMetadata = constructor[METADATA_FIELD_KEY]; - } - if (!metadata.deserializer) { - // @ts-ignore above is a check (!deser && !ctor) - objectMetadata.knownTypes.add(metadata.ctor); - } - if (metadata.keyType) - objectMetadata.knownTypes.add(metadata.keyType); - if (metadata.elementType) - metadata.elementType.forEach(function (elemCtor) { return objectMetadata.knownTypes.add(elemCtor); }); - // clear metadata of undefined properties to save memory - Object.keys(metadata) - .forEach(function (key) { return (metadata[key] === undefined) && delete metadata[key]; }); - objectMetadata.dataMembers.set(metadata.name, metadata); -} - -// CONCATENATED MODULE: ./src/typedjson/options-base.ts -var kAllOptions = [ - 'preserveNull', -]; -function extractOptionBase(from) { - var options = Object.keys(from) - .filter(function (key) { return kAllOptions.indexOf(key) > -1; }) - .reduce(function (obj, key) { - obj[key] = from[key]; - return obj; - }, {}); - return Object.keys(options).length > 0 ? options : undefined; -} -function getDefaultOptionOf(key) { - switch (key) { - case "preserveNull": - return false; - } - // never reached - return null; -} -function getOptionValue(key, options) { - if (options && options[key] != null) - return options[key]; - return getDefaultOptionOf(key); -} -function mergeOptions(existing, moreSpecific) { - return !moreSpecific - ? existing - : Object.assign({}, existing, moreSpecific); -} - -// 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; -} -function defaultTypeEmitter(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) { - targetObject.__type = sourceTypeMetadata && sourceTypeMetadata.name - ? sourceTypeMetadata.name - : nameof(sourceObject.constructor); - } -} -/** - * 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 serializer_Serializer = /** @class */ (function () { - function Serializer() { - this._typeHintEmitter = defaultTypeEmitter; - this._errorHandler = logError; - } - Serializer.prototype.setTypeHintEmitter = function (typeEmitterCallback) { - if (typeof typeEmitterCallback !== "function") { - throw new TypeError("'typeEmitterCallback' is not a function."); - } - this._typeHintEmitter = typeEmitterCallback; - }; - Serializer.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, memberOptions) { - if (memberName === void 0) { memberName = "object"; } - if (this.retrievePreserveNull(memberOptions) && sourceObject === null) - return null; - 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, memberOptions); - } - else if (isSetTypeInfo(typeInfo)) { - return this.convertAsSet(sourceObject, typeInfo.elementTypes[0], memberName, memberOptions); - } - else if (isMapTypeInfo(typeInfo)) { - return this.convertAsMap(sourceObject, typeInfo.keyType, typeInfo.elementTypes[0], memberName, memberOptions); - } - else if (isTypeTypedArray(typeInfo.selfType)) { - return this.convertAsTypedArray(sourceObject); - } - else if (typeof sourceObject === "object") { - return this.convertAsObject(sourceObject, typeInfo, memberName, memberOptions); - } - }; - /** - * 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, memberOptions) { - 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) { - if (sourceTypeMetadata.beforeSerializationMethodName) { - // check for member first - if (typeof sourceObject[sourceTypeMetadata.beforeSerializationMethodName] === "function") { - sourceObject[sourceTypeMetadata.beforeSerializationMethodName](); - } - // check for static - else if (typeof sourceObject.constructor[sourceTypeMetadata.beforeSerializationMethodName] === "function") { - sourceObject.constructor[sourceTypeMetadata.beforeSerializationMethodName](); - } - else { - this._errorHandler(new TypeError("beforeSerialization callback '" + nameof(sourceTypeMetadata.classType) + "." + sourceTypeMetadata.beforeSerializationMethodName + "' is not a method.")); - } - } - 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 = {}; - var classOptions_1 = mergeOptions(this.options, sourceMeta_1.options); - sourceMeta_1.dataMembers.forEach(function (objMemberMetadata) { - var objMemberOptions = mergeOptions(classOptions_1, objMemberMetadata.options); - var serialized; - if (objMemberMetadata.serializer) { - serialized = objMemberMetadata.serializer(sourceObject[objMemberMetadata.key]); - } - else if (objMemberMetadata.ctor) { - serialized = _this.convertSingleValue(sourceObject[objMemberMetadata.key], { - selfType: objMemberMetadata.ctor, - elementTypes: objMemberMetadata.elementType, - keyType: objMemberMetadata.keyType, - }, nameof(sourceMeta_1.classType) + "." + objMemberMetadata.key, objMemberOptions); - } - else { - throw new TypeError("Could not serialize " + objMemberMetadata.name + ", there is" - + " no constructor nor serialization function to use."); - } - if (isValueDefined(serialized) - || (_this.retrievePreserveNull(objMemberOptions) && serialized === null)) { - targetObject[objMemberMetadata.name] = serialized; - } - }); - } - 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; - }; - /** - * 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. - * @param memberOptions If converted as a member, the member options. - */ - Serializer.prototype.convertAsArray = function (sourceObject, expectedElementType, memberName, memberOptions) { - var _this = this; - 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 (!(_this.retrievePreserveNull(memberOptions) && element === null) - && !isInstanceOf(element, expectedElementType[0])) { - var expectedTypeName = nameof(expectedElementType[0]); - var actualTypeName = element && nameof(element.constructor); - throw new TypeError("Could not serialize " + memberName + "[" + i + "]:" + - (" expected '" + expectedTypeName + "', got '" + actualTypeName + "'.")); - } - }); - var typeInfoForElements = { - selfType: expectedElementType[0], - // For multidimensional arrays. - 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, memberOptions); }); - }; - /** - * 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. - * @param memberOptions If converted as a member, the member options. - * @returns - */ - Serializer.prototype.convertAsSet = function (sourceObject, expectedElementType, memberName, memberOptions) { - var _this = this; - if (memberName === void 0) { memberName = "object"; } - if (!expectedElementType) - throw new TypeError("Could not serialize " + memberName + " as Set: missing element type definition."); - var elementTypeInfo = { - selfType: expectedElementType, - }; - // 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, memberOptions); - // 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; - }; - /** - * 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. - * @param memberOptions If converted as a member, the member options. - */ - Serializer.prototype.convertAsMap = function (sourceObject, expectedKeyType, expectedElementType, memberName, memberOptions) { - 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."); - var elementTypeInfo = { - selfType: expectedElementType, - elementTypes: [expectedElementType] - }; - var keyTypeInfo = { - selfType: expectedKeyType - }; - if (memberName) - memberName += "[]"; - var resultArray = []; - var preserveNull = this.retrievePreserveNull(memberOptions); - // 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, memberOptions), - value: _this.convertSingleValue(value, elementTypeInfo, memberName, memberOptions), - }; - // We are not going to emit entries with undefined keys OR undefined values. - var keyDefined = isValueDefined(resultKeyValuePairObj.key); - var valueDefined = isValueDefined(resultKeyValuePairObj.value) - || (resultKeyValuePairObj.value === null && preserveNull); - if (keyDefined && valueDefined) { - resultArray.push(resultKeyValuePairObj); - } - }); - 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); - }; - Serializer.prototype.retrievePreserveNull = function (memberOptions) { - return getOptionValue('preserveNull', mergeOptions(this.options, memberOptions)); - }; - return Serializer; -}()); - - -// CONCATENATED MODULE: ./src/typedjson/deserializer.ts - - - -function defaultTypeResolver(sourceObject, knownTypes) { - if (sourceObject.__type) - return knownTypes.get(sourceObject.__type); -} -/** - * Utility class, converts a simple/untyped javascript object-tree to a typed object-tree. - * It is used after parsing a JSON-string. - */ -var deserializer_Deserializer = /** @class */ (function () { - function Deserializer() { - this._typeResolver = defaultTypeResolver; - this._errorHandler = logError; - } - 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; - }; - Deserializer.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, memberOptions) { - 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; - } - 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)); - } - // 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 = {}; - var classOptions_1 = mergeOptions(this.options, sourceMetadata_1.options); - // Deserialize by expected properties. - sourceMetadata_1.dataMembers.forEach(function (objMemberMetadata, propKey) { - var objMemberValue = sourceObject[propKey]; - var objMemberDebugName = nameof(sourceMetadata_1.classType) + "." + propKey; - var objMemberOptions = mergeOptions(classOptions_1, objMemberMetadata.options); - var revivedValue; - if (objMemberMetadata.deserializer) { - revivedValue = objMemberMetadata.deserializer(objMemberValue); - } - else if (objMemberMetadata.ctor) { - revivedValue = _this.convertSingleValue(objMemberValue, { - selfConstructor: objMemberMetadata.ctor, - elementConstructor: objMemberMetadata.elementType, - keyConstructor: objMemberMetadata.keyType, - knownTypes: knownTypeConstructors - }, objMemberDebugName, objMemberOptions); - } - else { - throw new TypeError("Cannot deserialize " + objMemberDebugName + " there is" - + " no constructor nor deserialization function to use."); - } - if (isValueDefined(revivedValue) - || (_this.retrievePreserveNull(objMemberOptions) && revivedValue === null)) { - sourceObjectWithDeserializedProperties_1[objMemberMetadata.key] = revivedValue; - } - else if (objMemberMetadata.isRequired) { - _this._errorHandler(new TypeError("Missing required member '" + objMemberDebugName + "'.")); - } - }); - // 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) { - // check for member first - if (typeof targetObject[sourceObjectMetadata.onDeserializedMethodName] === "function") { - targetObject[sourceObjectMetadata.onDeserializedMethodName](); - } - // check for static - else 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; - } - }; - Deserializer.prototype.convertSingleValue = function (sourceObject, typeInfo, memberName, memberOptions) { - if (memberName === void 0) { memberName = "object"; } - var expectedSelfType = typeInfo.selfConstructor; - var srcTypeNameForDebug = sourceObject ? nameof(sourceObject.constructor) : "undefined"; - if (this.retrievePreserveNull(memberOptions) && sourceObject === null) { - return null; - } - else if (!isValueDefined(sourceObject)) { - return; - } - else if (isDirectlyDeserializableNativeType(expectedSelfType)) { - if (sourceObject.constructor === expectedSelfType) { - return sourceObject; - } - else { - throw new TypeError(this._makeTypeErrorMessage(nameof(expectedSelfType), sourceObject.constructor, 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 || expectedSelfType === Float64Array) { - // Deserialize Float Array from number[]. - return this._convertAsFloatArray(sourceObject, expectedSelfType, srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === Uint8Array - || expectedSelfType === Uint8ClampedArray - || expectedSelfType === Uint16Array - || expectedSelfType === Uint32Array) { - // Deserialize Uint array from number[]. - return this._convertAsUintArray(sourceObject, expectedSelfType, 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 (Array.isArray(sourceObject)) - return this.convertAsArray(sourceObject, typeInfo, memberName, memberOptions); - else - throw new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)); - } - else if (expectedSelfType === Set) { - if (Array.isArray(sourceObject)) - return this.convertAsSet(sourceObject, typeInfo, memberName, memberOptions); - else - this._throwTypeMismatchError("Set", "Array", srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === Map) { - if (Array.isArray(sourceObject)) - return this.convertAsMap(sourceObject, typeInfo, memberName, memberOptions); - 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, memberOptions); - } - }; - Deserializer.prototype.convertAsArray = function (sourceObject, typeInfo, memberName, memberOptions) { - var _this = this; - if (memberName === void 0) { memberName = "object"; } - if (!(Array.isArray(sourceObject))) { - 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 = { - selfConstructor: typeInfo.elementConstructor[0], - elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [], - knownTypes: typeInfo.knownTypes - }; - 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, memberName + "[]", memberOptions); - } - 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; - } - }); - }; - Deserializer.prototype.convertAsSet = function (sourceObject, typeInfo, memberName, memberOptions) { - var _this = this; - if (memberName === void 0) { memberName = "object"; } - if (!(Array.isArray(sourceObject))) { - 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 = { - selfConstructor: typeInfo.elementConstructor[0], - elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [], - knownTypes: typeInfo.knownTypes - }; - var resultSet = new Set(); - sourceObject.forEach(function (element, i) { - try { - resultSet.add(_this.convertSingleValue(element, elementTypeInfo, memberName + "[" + i + "]", memberOptions)); - } - 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, memberOptions) { - var _this = this; - if (memberName === void 0) { memberName = "object"; } - if (!(Array.isArray(sourceObject))) - 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 - }; - var resultMap = new Map(); - sourceObject.forEach(function (element) { - try { - var key = _this.convertSingleValue(element.key, keyTypeInfo, memberName, memberOptions); - // Undefined/null keys not supported, skip if so. - if (isValueDefined(key)) { - resultMap.set(key, _this.convertSingleValue(element.value, valueTypeInfo, memberName + "[" + key + "]", memberOptions)); - } - } - catch (e) { - // Faulty entries are skipped, because a Map is not ordered, - // and skipping an entry does not affect others. - _this._errorHandler(e); - } - }); - return resultMap; - }; - Deserializer.prototype._convertAsFloatArray = function (sourceObject, arrayType, srcTypeNameForDebug, memberName) { - if (Array.isArray(sourceObject) && sourceObject.every(function (elem) { return !isNaN(elem); })) - return new arrayType(sourceObject); - return this._throwTypeMismatchError(arrayType.name, "a numeric source array", srcTypeNameForDebug, memberName); - }; - Deserializer.prototype._convertAsUintArray = function (sourceObject, arrayType, srcTypeNameForDebug, memberName) { - if (Array.isArray(sourceObject) && sourceObject.every(function (elem) { return !isNaN(elem); })) - return new arrayType(sourceObject.map(function (value) { return ~~value; })); - return this._throwTypeMismatchError(arrayType.name, "a numeric source array", srcTypeNameForDebug, memberName); - }; - Deserializer.prototype._throwTypeMismatchError = function (targetType, expectedSourceType, actualSourceType, memberName) { - throw new TypeError("Could not deserialize " + memberName + " as " + targetType + ":" - + (" expected " + expectedSourceType + ", got " + actualSourceType + ".")); - }; - Deserializer.prototype._makeTypeErrorMessage = function (expectedType, actualType, memberName) { - 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._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)); - }; - Deserializer.prototype.retrievePreserveNull = function (memberOptions) { - return getOptionValue('preserveNull', mergeOptions(this.options, memberOptions)); - }; - return Deserializer; -}()); - - -// 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)) - t[p] = s[p]; - } - return t; - }; - return parser_assign.apply(this, arguments); -}; - - - - - -var parser_TypedJSON = /** @class */ (function () { - /** - * 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. - */ - function TypedJSON(rootConstructor, settings) { - //#endregion - this.serializer = new serializer_Serializer(); - this.deserializer = new deserializer_Deserializer(); - this.globalKnownTypes = []; - this.indent = 0; - var rootMetadata = metadata_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 = function (ctor) { return nameof(ctor); }; - this.rootConstructor = rootConstructor; - this.errorHandler = function (error) { return logError(error); }; - if (settings) { - this.config(settings); - } - else if (TypedJSON._globalConfig) { - this.config({}); - } - } - //#region Static - TypedJSON.parse = function (object, rootType, settings) { - return new TypedJSON(rootType, settings).parse(object); - }; - TypedJSON.parseAsArray = function (object, elementType, settings, dimensions) { - return new TypedJSON(elementType, settings).parseAsArray(object, dimensions); - }; - TypedJSON.parseAsSet = function (object, elementType, settings) { - return new TypedJSON(elementType, settings).parseAsSet(object); - }; - TypedJSON.parseAsMap = function (object, keyType, valueType, settings) { - return new TypedJSON(valueType, settings).parseAsMap(object, keyType); - }; - TypedJSON.toPlainJson = function (object, rootType, settings) { - return new TypedJSON(rootType, settings).toPlainJson(object); - }; - TypedJSON.toPlainArray = function (object, elementType, dimensions, settings) { - return new TypedJSON(elementType, settings).toPlainArray(object, dimensions); - }; - TypedJSON.toPlainSet = function (object, elementType, settings) { - return new TypedJSON(elementType, settings).toPlainSet(object); - }; - TypedJSON.toPlainMap = function (object, keyCtor, valueCtor, settings) { - return new TypedJSON(valueCtor, settings).toPlainMap(object, keyCtor); - }; - TypedJSON.stringify = function (object, rootType, settings) { - return new TypedJSON(rootType, settings).stringify(object); - }; - TypedJSON.stringifyAsArray = function (object, elementType, dimensions, settings) { - return new TypedJSON(elementType, settings).stringifyAsArray(object, dimensions); - }; - TypedJSON.stringifyAsSet = function (object, elementType, settings) { - return new TypedJSON(elementType, settings).stringifyAsSet(object); - }; - TypedJSON.stringifyAsMap = function (object, keyCtor, valueCtor, settings) { - return new TypedJSON(valueCtor, settings).stringifyAsMap(object, keyCtor); - }; - TypedJSON.setGlobalConfig = function (config) { - if (this._globalConfig) { - Object.assign(this._globalConfig, config); - } - else { - this._globalConfig = config; - } - }; - /** - * Configures TypedJSON through a settings object. - * @param settings The configuration settings object. - */ - TypedJSON.prototype.config = function (settings) { - if (TypedJSON._globalConfig) { - settings = parser_assign(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))); - } - } - var options = extractOptionBase(settings); - this.serializer.options = options; - this.deserializer.options = options; - 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(function (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. - */ - TypedJSON.prototype.parse = function (object) { - var _this = this; - var json = parseToJSObject(object, this.rootConstructor); - var rootMetadata = metadata_JsonObjectMetadata.getFromConstructor(this.rootConstructor); - var result; - var knownTypes = new Map(); - this.globalKnownTypes.filter(function (ktc) { return ktc; }).forEach(function (knownTypeCtor) { - knownTypes.set(_this.nameResolver(knownTypeCtor), knownTypeCtor); - }); - if (rootMetadata) { - rootMetadata.knownTypes.forEach(function (knownTypeCtor) { - knownTypes.set(_this.nameResolver(knownTypeCtor), knownTypeCtor); - }); - } - try { - result = this.deserializer.convertSingleValue(json, { - selfConstructor: this.rootConstructor, - knownTypes: knownTypes, - }); - } - catch (e) { - this.errorHandler(e); - } - return result; - }; - TypedJSON.prototype.parseAsArray = function (object, dimensions) { - if (dimensions === void 0) { dimensions = 1; } - var 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 []; - }; - TypedJSON.prototype.parseAsSet = function (object) { - var 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(); - }; - TypedJSON.prototype.parseAsMap = function (object, keyConstructor) { - var 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. - */ - 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; - objectMetadata.beforeSerializationMethodName = options.beforeSerialization; - // T extend Object so it is fine - objectMetadata.initializerCallback = options.initializer; - if (options.name) { - objectMetadata.name = options.name; - } - var optionsBase = extractOptionBase(options); - if (optionsBase) { - objectMetadata.options = optionsBase; - } - // 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. " + MISSING_REFLECT_CONF_MSG); - 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; - } - } - 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, - isRequired: options.isRequired, - options: extractOptionBase(options), - 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. " + MISSING_REFLECT_CONF_MSG); - return; - } - injectMetadataInformation(target, propKey, { - ctor: Array, - elementType: createArrayElementType(elementConstructor, dimensions), - emitDefaultValue: options.emitDefaultValue, - isRequired: options.isRequired, - options: extractOptionBase(options), - key: propKey.toString(), - name: options.name || propKey.toString(), - deserializer: options.deserializer, - serializer: options.serializer, - }); - }; -} -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. " + MISSING_REFLECT_CONF_MSG); - return; - } - injectMetadataInformation(target, propKey, { - ctor: Set, - elementType: [elementConstructor], - emitDefaultValue: options.emitDefaultValue, - isRequired: options.isRequired, - options: extractOptionBase(options), - key: propKey.toString(), - name: options.name || propKey.toString(), - deserializer: options.deserializer, - serializer: options.serializer, - }); - }; -} - -// 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. " + MISSING_REFLECT_CONF_MSG); - return; - } - injectMetadataInformation(target, propKey, { - ctor: Map, - elementType: [valueConstructor], - keyType: keyConstructor, - emitDefaultValue: options.emitDefaultValue, - isRequired: options.isRequired, - options: extractOptionBase(options), - key: propKey.toString(), - name: options.name || propKey.toString(), - deserializer: options.deserializer, - serializer: options.serializer, - }); - }; -} - -// CONCATENATED MODULE: ./src/typedjson/to-json.ts - -function toJson(optionsOrTarget) { - if (typeof optionsOrTarget === 'function') { - // used directly - toJsonDecorator(optionsOrTarget, {}); - return; - } - // used as a factory - return function (target) { - toJsonDecorator(target, optionsOrTarget); - }; -} -function toJsonDecorator(target, options) { - if (!options.overwrite && target.prototype.toJSON) { - throw new Error(target.name + " already has toJSON defined!"); - } - target.prototype.toJSON = function () { - return parser_TypedJSON.toPlainJson(this, Object.getPrototypeOf(this).constructor); - }; -} - -// 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; }); -/* concated harmony reexport toJson */__webpack_require__.d(__webpack_exports__, "toJson", function() { return toJson; }); - - - - - - - - - -/***/ }) -/******/ ]); -}); -//# sourceMappingURL=typedjson.js.map \ No newline at end of file diff --git a/js/typedjson.js.map b/js/typedjson.js.map deleted file mode 100644 index 029e9ae..0000000 --- a/js/typedjson.js.map +++ /dev/null @@ -1 +0,0 @@ -{"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/options-base.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/to-json.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 const MISSING_REFLECT_CONF_MSG = 'Are you sure, that you have both \"experimentalDecorators\"' +\n ' and \"emitDecoratorMetadata\" in your tsconfig.json?';\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 isDirectlyDeserializableNativeType(type: Function): boolean\n{\n return !!(~[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 }\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 return \"undefined\";\n}\n","import { nameof, logError, METADATA_FIELD_KEY, isDirectlySerializableNativeType, isTypeTypedArray } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\nimport { OptionsBase } from \"./options-base\";\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 options?: OptionsBase;\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 options?: OptionsBase;\n\n public onDeserializedMethodName?: string;\n\n public beforeSerializationMethodName?: 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 // clear metadata of undefined properties to save memory\n (Object.keys(metadata) as [keyof JsonMemberMetadata])\n .forEach((key) => (metadata[key] === undefined) && delete metadata[key]);\n objectMetadata.dataMembers.set(metadata.name, metadata);\n}\n","/**\n * This options cascade through the annotations. Options set\n * in the more specific place override the previous option.\n * Ex. @jsonMember overrides TypedJson options.\n */\nexport interface OptionsBase {\n /**\n * Whether to preserve null in the JSON output. When false it\n * will not emit nor store the property if its value is null.\n * Default: false.\n */\n preserveNull?: boolean;\n}\n\nconst kAllOptions: (keyof OptionsBase)[] = [\n 'preserveNull',\n];\n\nexport function extractOptionBase(from: {[key: string]: any} & OptionsBase): OptionsBase|undefined {\n const options = Object.keys(from)\n .filter(key => (kAllOptions as string[]).indexOf(key) > -1)\n .reduce((obj, key) => {\n obj[key] = from[key];\n return obj;\n }, {} as any);\n return Object.keys(options).length > 0 ? options : undefined;\n}\n\nexport function getDefaultOptionOf(key: K): Required[K] {\n switch (key) {\n case \"preserveNull\":\n return false;\n }\n // never reached\n return null as any;\n}\n\nexport function getOptionValue(\n key: K,\n options?: OptionsBase,\n): Required[K] {\n if (options && options[key] != null) return options[key]!;\n return getDefaultOptionOf(key);\n}\n\nexport function mergeOptions(\n existing?: OptionsBase,\n moreSpecific?: OptionsBase,\n): OptionsBase|undefined {\n return !moreSpecific\n ? existing\n : Object.assign(\n {},\n existing,\n moreSpecific,\n );\n}\n","import {\n isDirectlySerializableNativeType,\n isInstanceOf,\n isTypeTypedArray,\n isValueDefined,\n logError,\n nameof,\n} from \"./helpers\";\nimport { IndexedObject } from \"./types\";\nimport { JsonObjectMetadata } from \"./metadata\";\nimport { getOptionValue, mergeOptions, OptionsBase } from \"./options-base\";\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\nexport type TypeHintEmitter\n = (\n targetObject: IndexedObject,\n sourceObject: IndexedObject,\n expectedSourceType: Function,\n sourceTypeMetadata?: JsonObjectMetadata,\n ) => void;\n\nfunction defaultTypeEmitter(\n targetObject: IndexedObject,\n sourceObject: IndexedObject,\n expectedSourceType: Function,\n sourceTypeMetadata?: JsonObjectMetadata,\n) {\n // By default, we put a \"__type\" property on the output object if the actual object is not the\n // same as the expected one, so that deserialization will know what to deserialize into (given\n // the required known-types are defined, and the object is a valid subtype of the expected type).\n if (sourceObject.constructor !== expectedSourceType)\n {\n targetObject.__type = sourceTypeMetadata && sourceTypeMetadata.name\n ? sourceTypeMetadata.name\n : nameof(sourceObject.constructor);\n }\n}\n\n/**\n * Utility class, converts a typed object tree (i.e. a tree of class instances, arrays of class\n * instances, and so on) to an untyped javascript object (also called \"simple javascript object\"),\n * 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\n * 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 public options?: OptionsBase;\n private _typeHintEmitter: TypeHintEmitter = defaultTypeEmitter;\n private _errorHandler: (error: Error) => void = logError;\n\n public setTypeHintEmitter(typeEmitterCallback: TypeHintEmitter)\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(\n sourceObject: any,\n typeInfo: IScopeTypeInfo,\n memberName: string = \"object\",\n memberOptions?: OptionsBase,\n ): any {\n if (this.retrievePreserveNull(memberOptions) && sourceObject === null) return null;\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(\n `Could not serialize '${memberName}': expected '${expectedName}', got '${actualName}'.`),\n );\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, memberOptions);\n }\n else if (isSetTypeInfo(typeInfo))\n {\n return this.convertAsSet(sourceObject, typeInfo.elementTypes[0], memberName, memberOptions);\n }\n else if (isMapTypeInfo(typeInfo))\n {\n return this.convertAsMap(sourceObject, typeInfo.keyType, typeInfo.elementTypes[0], memberName, memberOptions);\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, memberOptions);\n }\n }\n\n /**\n * Performs the conversion of a typed object (usually a class instance) to a simple\n * javascript object for serialization.\n */\n public convertAsObject(\n sourceObject: IndexedObject,\n typeInfo: IScopeTypeInfo,\n memberName?: string,\n memberOptions?: OptionsBase,\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\n if (sourceTypeMetadata.beforeSerializationMethodName) {\n // check for member first\n if (typeof (sourceObject as any)[sourceTypeMetadata.beforeSerializationMethodName] === \"function\")\n {\n (sourceObject as any)[sourceTypeMetadata.beforeSerializationMethodName]();\n }\n // check for static\n else if (typeof (sourceObject.constructor as any)[sourceTypeMetadata.beforeSerializationMethodName] === \"function\")\n {\n (sourceObject.constructor as any)[sourceTypeMetadata.beforeSerializationMethodName]();\n }\n else \n {\n this._errorHandler(new TypeError(\n `beforeSerialization callback '${nameof(sourceTypeMetadata.classType)}.${sourceTypeMetadata.beforeSerializationMethodName}' is not a method.`\n ));\n }\n }\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),\n // and perform recursive conversion on each of them. The converted objects are put on the 'targetObject',\n // which is what will be put into 'JSON.stringify' finally.\n targetObject = {};\n\n const classOptions = mergeOptions(this.options, sourceMeta.options);\n\n sourceMeta.dataMembers.forEach((objMemberMetadata) =>\n {\n const objMemberOptions = mergeOptions(classOptions, objMemberMetadata.options);\n let serialized;\n if (objMemberMetadata.serializer) {\n serialized = objMemberMetadata.serializer(sourceObject[objMemberMetadata.key]);\n } else if (objMemberMetadata.ctor) {\n serialized = this.convertSingleValue(\n sourceObject[objMemberMetadata.key],\n {\n selfType: objMemberMetadata.ctor,\n elementTypes: objMemberMetadata.elementType,\n keyType: objMemberMetadata.keyType,\n },\n `${nameof(sourceMeta.classType)}.${objMemberMetadata.key}`,\n objMemberOptions,\n );\n } else {\n throw new TypeError(\n `Could not serialize ${objMemberMetadata.name}, there is`\n + ` no constructor nor serialization function to use.`,\n );\n }\n\n if (isValueDefined(serialized)\n || (this.retrievePreserveNull(objMemberOptions) && serialized === null)\n ) {\n targetObject[objMemberMetadata.name] = serialized;\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 * @param memberOptions If converted as a member, the member options.\n */\n public convertAsArray(\n sourceObject: any[],\n expectedElementType: Function[],\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ): any[] {\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\n // value emitted during serialization. This is so that invalid element types don't unexpectedly\n // 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 (!(this.retrievePreserveNull(memberOptions) && element === null)\n && !isInstanceOf(element, expectedElementType[0])\n ) {\n const expectedTypeName = nameof(expectedElementType[0]);\n const actualTypeName = element && nameof(element.constructor);\n throw new TypeError(`Could not serialize ${memberName}[${i}]:` +\n ` expected '${expectedTypeName}', got '${actualTypeName}'.`);\n }\n });\n\n const typeInfoForElements: IScopeTypeInfo = {\n selfType: expectedElementType[0],\n // For multidimensional arrays.\n elementTypes: expectedElementType.length > 1 ? expectedElementType.slice(1) : [],\n };\n\n if (memberName)\n {\n // Just for debugging purposes.\n memberName += \"[]\";\n }\n\n return sourceObject.map(\n element => this.convertSingleValue(\n element, typeInfoForElements, memberName, memberOptions\n ),\n );\n }\n\n /**\n * Performs the conversion of a set of typed objects (or primitive values) into an array\n * of simple javascript objects.\n *\n * @param sourceObject\n * @param expectedElementType The constructor of the expected Set elements\n * (e.g. `Number` for `Set`, or `MyClass` for `Set`).\n * @param memberName Name of the object being serialized, used for debugging purposes.\n * @param memberOptions If converted as a member, the member options.\n * @returns\n */\n public convertAsSet(\n sourceObject: Set,\n expectedElementType: Function,\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ): any[] {\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.\n // (TODO: clarification needed)\n sourceObject.forEach(element =>\n {\n let resultElement = this.convertSingleValue(element, elementTypeInfo, memberName, memberOptions);\n\n // Add to output if the source element was undefined, OR the converted element is defined.\n // This will add intentionally undefined values to output, but not values that became undefined\n // 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\n * of simple javascript objects with `key` and `value` properties.\n *\n * @param sourceObject\n * @param expectedKeyType The constructor of the expected Map keys\n * (e.g. `Number` for `Map`, or `MyClass` for `Map`).\n * @param expectedElementType The constructor of the expected Map values\n * (e.g. `Number` for `Map`, or `MyClass` for `Map`).\n * @param memberName Name of the object being serialized, used for debugging purposes.\n * @param memberOptions If converted as a member, the member options.\n */\n public convertAsMap(\n sourceObject: Map,\n expectedKeyType: Function,\n expectedElementType: Function,\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ): Array<{ key: any, value: any }> {\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 const resultArray: Array<{ key: any, value: any }> = [];\n const preserveNull = this.retrievePreserveNull(memberOptions);\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, memberOptions),\n value: this.convertSingleValue(value, elementTypeInfo, memberName, memberOptions),\n };\n\n // We are not going to emit entries with undefined keys OR undefined values.\n const keyDefined = isValueDefined(resultKeyValuePairObj.key);\n const valueDefined = isValueDefined(resultKeyValuePairObj.value)\n || (resultKeyValuePairObj.value === null && preserveNull);\n if (keyDefined && valueDefined)\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\n * 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\n * returning that string.\n */\n public convertAsDataView(dataView: DataView)\n {\n return this.convertAsArrayBuffer(dataView.buffer);\n }\n\n private retrievePreserveNull(memberOptions?: OptionsBase): boolean {\n return getOptionValue('preserveNull', mergeOptions(this.options, memberOptions));\n }\n}\n","import { nameof, logError, isSubtypeOf, isValueDefined, isDirectlyDeserializableNativeType } from \"./helpers\";\nimport { Constructor, IndexedObject } from \"./types\";\nimport { JsonObjectMetadata } from \"./metadata\";\nimport { getOptionValue, mergeOptions, OptionsBase } from \"./options-base\";\n\nexport interface IScopeTypeInfo\n{\n selfConstructor: Function;\n elementConstructor?: Function[];\n keyConstructor?: Function;\n knownTypes: Map;\n}\n\nexport type TypeResolver = (sourceObject: Object, knownTypes: Map) => Function|undefined|null;\n\nfunction defaultTypeResolver(sourceObject: any, knownTypes: Map): Function|undefined {\n if (sourceObject.__type) return knownTypes.get(sourceObject.__type);\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 public options?: OptionsBase;\n\n private _typeResolver: TypeResolver = defaultTypeResolver;\n private _nameResolver?: (ctor: Function) => string;\n private _errorHandler: (error: Error) => void = logError;\n\n public setNameResolver(nameResolverCallback: (ctor: Function) => string)\n {\n this._nameResolver = nameResolverCallback;\n }\n\n public setTypeResolver(typeResolverCallback: TypeResolver)\n {\n if (typeof typeResolverCallback !== \"function\")\n {\n throw new TypeError(\"'typeResolverCallback' is not a function.\");\n }\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 memberOptions?: OptionsBase,\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 const 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 const classOptions = mergeOptions(this.options, sourceMetadata.options);\n\n // Deserialize by expected properties.\n sourceMetadata.dataMembers.forEach((objMemberMetadata, propKey) =>\n {\n const objMemberValue = sourceObject[propKey];\n const objMemberDebugName = `${nameof(sourceMetadata.classType)}.${propKey}`;\n const objMemberOptions = mergeOptions(classOptions, objMemberMetadata.options);\n\n let revivedValue;\n if (objMemberMetadata.deserializer) {\n revivedValue = objMemberMetadata.deserializer(objMemberValue);\n } else if (objMemberMetadata.ctor) {\n revivedValue = this.convertSingleValue(\n objMemberValue,\n {\n selfConstructor: objMemberMetadata.ctor,\n elementConstructor: objMemberMetadata.elementType,\n keyConstructor: objMemberMetadata.keyType,\n knownTypes: knownTypeConstructors\n },\n objMemberDebugName,\n objMemberOptions,\n );\n } else {\n throw new TypeError(\n `Cannot deserialize ${objMemberDebugName} there is`\n + ` no constructor nor deserialization function to use.`,\n );\n }\n\n if (isValueDefined(revivedValue)\n || (this.retrievePreserveNull(objMemberOptions) && revivedValue === null)\n ) {\n sourceObjectWithDeserializedProperties[objMemberMetadata.key] = revivedValue;\n }\n else if (objMemberMetadata.isRequired)\n {\n this._errorHandler(new TypeError(`Missing required member '${objMemberDebugName}'.`));\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 // check for member first\n if (typeof (targetObject as any)[sourceObjectMetadata.onDeserializedMethodName] === \"function\")\n {\n (targetObject as any)[sourceObjectMetadata.onDeserializedMethodName]();\n }\n // check for static\n else 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(\n sourceObject: any,\n typeInfo: IScopeTypeInfo,\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ) {\n let expectedSelfType = typeInfo.selfConstructor;\n let srcTypeNameForDebug = sourceObject ? nameof(sourceObject.constructor) : \"undefined\";\n\n if (this.retrievePreserveNull(memberOptions) && sourceObject === null)\n {\n return null;\n }\n else if (!isValueDefined(sourceObject))\n {\n return;\n }\n else if (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 || expectedSelfType === Float64Array)\n {\n // Deserialize Float Array from number[].\n return this._convertAsFloatArray(\n sourceObject,\n expectedSelfType as any,\n srcTypeNameForDebug,\n memberName,\n );\n }\n else if (\n expectedSelfType === Uint8Array\n || expectedSelfType === Uint8ClampedArray\n || expectedSelfType === Uint16Array\n || expectedSelfType === Uint32Array\n ) {\n // Deserialize Uint array from number[].\n return this._convertAsUintArray(\n sourceObject,\n expectedSelfType as any,\n srcTypeNameForDebug,\n memberName,\n );\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 (Array.isArray(sourceObject))\n return this.convertAsArray(sourceObject, typeInfo, memberName, memberOptions);\n else\n throw new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName));\n }\n else if (expectedSelfType === Set)\n {\n if (Array.isArray(sourceObject))\n return this.convertAsSet(sourceObject, typeInfo, memberName, memberOptions);\n else\n this._throwTypeMismatchError(\"Set\", \"Array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Map)\n {\n if (Array.isArray(sourceObject))\n return this.convertAsMap(sourceObject, typeInfo, memberName, memberOptions);\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, memberOptions);\n }\n }\n\n public convertAsArray(\n sourceObject: any,\n typeInfo: IScopeTypeInfo,\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ): any[] {\n if (!(Array.isArray(sourceObject)))\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, `${memberName}[]`, memberOptions);\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(\n sourceObject: any,\n typeInfo: IScopeTypeInfo,\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ): Set {\n if (!(Array.isArray(sourceObject)))\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(\n element,\n elementTypeInfo,\n `${memberName}[${i}]`,\n memberOptions,\n ));\n }\n catch (e)\n {\n // Faulty entries are skipped, because a Set is not ordered, and skipping an entry\n // does not affect others.\n this._errorHandler(e);\n }\n });\n\n return resultSet;\n }\n\n public convertAsMap(\n sourceObject: any,\n typeInfo: IScopeTypeInfo,\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ): Map {\n if (!(Array.isArray(sourceObject)))\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, memberName, memberOptions);\n\n // Undefined/null keys not supported, skip if so.\n if (isValueDefined(key))\n {\n resultMap.set(\n key,\n this.convertSingleValue(\n element.value,\n valueTypeInfo,\n `${memberName}[${key}]`,\n memberOptions,\n ),\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 _convertAsFloatArray(\n sourceObject: any,\n arrayType: Constructor,\n srcTypeNameForDebug: string,\n memberName: string,\n ): T {\n if (Array.isArray(sourceObject) && sourceObject.every(elem => !isNaN(elem)))\n return new arrayType(sourceObject);\n return this._throwTypeMismatchError(\n arrayType.name,\n \"a numeric source array\",\n srcTypeNameForDebug,\n memberName,\n );\n }\n\n private _convertAsUintArray(\n sourceObject: any,\n arrayType: Constructor,\n srcTypeNameForDebug: string,\n memberName: string,\n ): T {\n if (Array.isArray(sourceObject) && sourceObject.every(elem => !isNaN(elem)))\n return new arrayType(sourceObject.map(value => ~~value));\n return this._throwTypeMismatchError(\n arrayType.name,\n \"a numeric source array\",\n srcTypeNameForDebug,\n memberName,\n );\n }\n\n private _throwTypeMismatchError(\n targetType: string,\n expectedSourceType: string,\n actualSourceType: string,\n memberName: string,\n ): never {\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: string)\n {\n const expectedTypeName = (typeof expectedType === \"function\") ? nameof(expectedType) : expectedType;\n const 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 _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 private retrievePreserveNull(memberOptions?: OptionsBase): boolean {\n return getOptionValue('preserveNull', mergeOptions(this.options, memberOptions));\n }\n}\n","import { Constructor } from \"./typedjson/types\";\nimport { Serializer, TypeHintEmitter } from \"./typedjson/serializer\";\nimport { Deserializer, TypeResolver } from \"./typedjson/deserializer\";\nimport { JsonObjectMetadata } from \"./typedjson/metadata\";\nimport { logError, logWarning, nameof, parseToJSObject } from \"./typedjson/helpers\";\nimport { extractOptionBase, OptionsBase } from \"./typedjson/options-base\";\n\nexport type JsonTypes = Object|boolean|string|number|null|undefined;\nexport { TypeResolver, TypeHintEmitter };\n\nexport interface ITypedJSONSettings extends OptionsBase\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?: TypeResolver;\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?: TypeHintEmitter;\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 ): Object[]|undefined {\n return new TypedJSON(elementType, settings).toPlainSet(object);\n }\n\n public static toPlainMap(\n object: Map,\n keyCtor: Constructor,\n valueCtor: Constructor,\n settings?: ITypedJSONSettings,\n ): { key: any, value: any }[]|undefined {\n return new TypedJSON(valueCtor, settings).toPlainMap(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 const options = extractOptionBase(settings);\n this.serializer.options = options;\n this.deserializer.options = options;\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(\n 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\";\nimport { extractOptionBase, OptionsBase } from \"./options-base\";\n\nexport type InitializerCallback = (sourceObject: T, rawSourceObject: T) => T;\n\nexport interface IJsonObjectOptionsBase extends OptionsBase\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 of a static or instance method to call before the serialization\n * of the typed object is started.\n */\n beforeSerialization?: 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 * Function to call before deserializing and initializing the object, accepting two arguments:\n * (1) sourceObject, an 'Object' instance with all properties already deserialized, and\n * (2) rawSourceObject, a raw 'Object' instance representation of the current object in\n * the serialized JSON (i.e. without deserialized properties).\n */\n initializer: InitializerCallback;\n}\n\nexport interface IJsonObjectOptions extends IJsonObjectOptionsBase\n{\n /**\n * Function to call before deserializing and initializing the object, accepting two arguments:\n * (1) sourceObject, an 'Object' instance with all properties already deserialized, and\n * (2) rawSourceObject, a raw 'Object' instance representation of the current object in\n * the serialized JSON (i.e. without deserialized properties).\n */\n initializer?: InitializerCallback;\n}\n\n/**\n * Marks that a class with a parameterized constructor is serializable using TypedJSON, with additional\n * 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 objectMetadata.beforeSerializationMethodName = options.beforeSerialization;\n \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 const optionsBase = extractOptionBase(options);\n if (optionsBase)\n {\n objectMetadata.options = optionsBase;\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, MISSING_REFLECT_CONF_MSG,\n} from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\nimport { extractOptionBase, OptionsBase } from \"./options-base\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonMemberOptions extends OptionsBase\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. ${MISSING_REFLECT_CONF_MSG}`);\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,\n isRequired: options.isRequired,\n options: extractOptionBase(options),\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, MISSING_REFLECT_CONF_MSG } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\nimport { extractOptionBase, OptionsBase } from \"./options-base\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonArrayMemberOptions extends OptionsBase\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. ${MISSING_REFLECT_CONF_MSG}`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Array,\n elementType: createArrayElementType(elementConstructor, dimensions),\n emitDefaultValue: options.emitDefaultValue,\n isRequired: options.isRequired,\n options: extractOptionBase(options),\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 { isReflectMetadataSupported, logError, MISSING_REFLECT_CONF_MSG, nameof } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\nimport { extractOptionBase, OptionsBase } from \"./options-base\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonSetMemberOptions extends OptionsBase\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 const decoratorName = `@jsonSetMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof elementConstructor !== \"function\")\n {\n 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 (isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Set)\n {\n logError(`${decoratorName}: property is not a Set. ${MISSING_REFLECT_CONF_MSG}`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Set,\n elementType: [elementConstructor],\n emitDefaultValue: options.emitDefaultValue,\n isRequired: options.isRequired,\n options: extractOptionBase(options),\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, MISSING_REFLECT_CONF_MSG } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\nimport { extractOptionBase, OptionsBase } from \"./options-base\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonMapMemberOptions extends OptionsBase\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. ${MISSING_REFLECT_CONF_MSG}`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Map,\n elementType: [valueConstructor],\n keyType: keyConstructor,\n emitDefaultValue: options.emitDefaultValue,\n isRequired: options.isRequired,\n options: extractOptionBase(options),\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n","import { TypedJSON } from \"../parser\";\n\n/**\n * Options for the @toJson decorator.\n */\nexport interface IToJsonOptions {\n /**\n * When set to true it will overwrite any toJSON already existing on the prototype.\n */\n overwrite?: boolean;\n}\n\n/**\n * Decorator that will generate toJSON function on the class prototype that allows\n * JSON.stringify to be used instead of TypedJSON.stringify. Under the hood it will\n * simply delegate to TypedJSON.\n * By default it will throw if the prototype already has a toJSON function defined.\n * @param target the class which prototype should be modified.\n */\nexport function toJson(target: Function): void;\n/**\n * Decorator factory that accepts the options interface.\n * @param options for configuring the toJSON creation.\n */\nexport function toJson(options: IToJsonOptions): ((target: Function) => void);\nexport function toJson(optionsOrTarget: IToJsonOptions | Function\n): ((target: Function) => void) | void {\n if (typeof optionsOrTarget === 'function') {\n // used directly\n toJsonDecorator(optionsOrTarget, {});\n return;\n }\n // used as a factory\n return (target: Function) => {\n toJsonDecorator(target, optionsOrTarget);\n }\n}\n\nfunction toJsonDecorator(target: Function, options: IToJsonOptions): void {\n if (!options.overwrite && target.prototype.toJSON) {\n throw new Error(`${target.name} already has toJSON defined!`);\n }\n target.prototype.toJSON = function () {\n return TypedJSON.toPlainJson(this, Object.getPrototypeOf(this).constructor);\n }\n}\n","export { TypedJSON, ITypedJSONSettings, JsonTypes, TypeResolver, TypeHintEmitter } 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\";\nexport { toJson } from \"./typedjson/to-json\";\n"],"sourceRoot":""} \ No newline at end of file diff --git a/js/typedjson.min.js b/js/typedjson.min.js deleted file mode 100644 index 784cb0f..0000000 --- a/js/typedjson.min.js +++ /dev/null @@ -1,3 +0,0 @@ -// [typedjson] Version: 1.5.1 - 2020-02-09 - !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 n={},o.m=t=[function(e,r,t){"use strict";t.r(r);var n=function(){for(var e=0,r=0,t=arguments.length;r(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 isDirectlyDeserializableNativeType(type: Function): boolean\n{\n return !!(~[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 }\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 return \"undefined\";\n}\n","import { nameof, logError, METADATA_FIELD_KEY, isDirectlySerializableNativeType, isTypeTypedArray } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\nimport { OptionsBase } from \"./options-base\";\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 options?: OptionsBase;\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 options?: OptionsBase;\n\n public onDeserializedMethodName?: string;\n\n public beforeSerializationMethodName?: 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 // clear metadata of undefined properties to save memory\n (Object.keys(metadata) as [keyof JsonMemberMetadata])\n .forEach((key) => (metadata[key] === undefined) && delete metadata[key]);\n objectMetadata.dataMembers.set(metadata.name, metadata);\n}\n","/**\n * This options cascade through the annotations. Options set\n * in the more specific place override the previous option.\n * Ex. @jsonMember overrides TypedJson options.\n */\nexport interface OptionsBase {\n /**\n * Whether to preserve null in the JSON output. When false it\n * will not emit nor store the property if its value is null.\n * Default: false.\n */\n preserveNull?: boolean;\n}\n\nconst kAllOptions: (keyof OptionsBase)[] = [\n 'preserveNull',\n];\n\nexport function extractOptionBase(from: {[key: string]: any} & OptionsBase): OptionsBase|undefined {\n const options = Object.keys(from)\n .filter(key => (kAllOptions as string[]).indexOf(key) > -1)\n .reduce((obj, key) => {\n obj[key] = from[key];\n return obj;\n }, {} as any);\n return Object.keys(options).length > 0 ? options : undefined;\n}\n\nexport function getDefaultOptionOf(key: K): Required[K] {\n switch (key) {\n case \"preserveNull\":\n return false;\n }\n // never reached\n return null as any;\n}\n\nexport function getOptionValue(\n key: K,\n options?: OptionsBase,\n): Required[K] {\n if (options && options[key] != null) return options[key]!;\n return getDefaultOptionOf(key);\n}\n\nexport function mergeOptions(\n existing?: OptionsBase,\n moreSpecific?: OptionsBase,\n): OptionsBase|undefined {\n return !moreSpecific\n ? existing\n : Object.assign(\n {},\n existing,\n moreSpecific,\n );\n}\n","import {\n isDirectlySerializableNativeType,\n isInstanceOf,\n isTypeTypedArray,\n isValueDefined,\n logError,\n nameof,\n} from \"./helpers\";\nimport { IndexedObject } from \"./types\";\nimport { JsonObjectMetadata } from \"./metadata\";\nimport { getOptionValue, mergeOptions, OptionsBase } from \"./options-base\";\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\nexport type TypeHintEmitter\n = (\n targetObject: IndexedObject,\n sourceObject: IndexedObject,\n expectedSourceType: Function,\n sourceTypeMetadata?: JsonObjectMetadata,\n ) => void;\n\nfunction defaultTypeEmitter(\n targetObject: IndexedObject,\n sourceObject: IndexedObject,\n expectedSourceType: Function,\n sourceTypeMetadata?: JsonObjectMetadata,\n) {\n // By default, we put a \"__type\" property on the output object if the actual object is not the\n // same as the expected one, so that deserialization will know what to deserialize into (given\n // the required known-types are defined, and the object is a valid subtype of the expected type).\n if (sourceObject.constructor !== expectedSourceType)\n {\n targetObject.__type = sourceTypeMetadata && sourceTypeMetadata.name\n ? sourceTypeMetadata.name\n : nameof(sourceObject.constructor);\n }\n}\n\n/**\n * Utility class, converts a typed object tree (i.e. a tree of class instances, arrays of class\n * instances, and so on) to an untyped javascript object (also called \"simple javascript object\"),\n * 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\n * 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 public options?: OptionsBase;\n private _typeHintEmitter: TypeHintEmitter = defaultTypeEmitter;\n private _errorHandler: (error: Error) => void = logError;\n\n public setTypeHintEmitter(typeEmitterCallback: TypeHintEmitter)\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(\n sourceObject: any,\n typeInfo: IScopeTypeInfo,\n memberName: string = \"object\",\n memberOptions?: OptionsBase,\n ): any {\n if (this.retrievePreserveNull(memberOptions) && sourceObject === null) return null;\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(\n `Could not serialize '${memberName}': expected '${expectedName}', got '${actualName}'.`),\n );\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, memberOptions);\n }\n else if (isSetTypeInfo(typeInfo))\n {\n return this.convertAsSet(sourceObject, typeInfo.elementTypes[0], memberName, memberOptions);\n }\n else if (isMapTypeInfo(typeInfo))\n {\n return this.convertAsMap(sourceObject, typeInfo.keyType, typeInfo.elementTypes[0], memberName, memberOptions);\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, memberOptions);\n }\n }\n\n /**\n * Performs the conversion of a typed object (usually a class instance) to a simple\n * javascript object for serialization.\n */\n public convertAsObject(\n sourceObject: IndexedObject,\n typeInfo: IScopeTypeInfo,\n memberName?: string,\n memberOptions?: OptionsBase,\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\n if (sourceTypeMetadata.beforeSerializationMethodName) {\n // check for member first\n if (typeof (sourceObject as any)[sourceTypeMetadata.beforeSerializationMethodName] === \"function\")\n {\n (sourceObject as any)[sourceTypeMetadata.beforeSerializationMethodName]();\n }\n // check for static\n else if (typeof (sourceObject.constructor as any)[sourceTypeMetadata.beforeSerializationMethodName] === \"function\")\n {\n (sourceObject.constructor as any)[sourceTypeMetadata.beforeSerializationMethodName]();\n }\n else \n {\n this._errorHandler(new TypeError(\n `beforeSerialization callback '${nameof(sourceTypeMetadata.classType)}.${sourceTypeMetadata.beforeSerializationMethodName}' is not a method.`\n ));\n }\n }\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),\n // and perform recursive conversion on each of them. The converted objects are put on the 'targetObject',\n // which is what will be put into 'JSON.stringify' finally.\n targetObject = {};\n\n const classOptions = mergeOptions(this.options, sourceMeta.options);\n\n sourceMeta.dataMembers.forEach((objMemberMetadata) =>\n {\n const objMemberOptions = mergeOptions(classOptions, objMemberMetadata.options);\n let serialized;\n if (objMemberMetadata.serializer) {\n serialized = objMemberMetadata.serializer(sourceObject[objMemberMetadata.key]);\n } else if (objMemberMetadata.ctor) {\n serialized = this.convertSingleValue(\n sourceObject[objMemberMetadata.key],\n {\n selfType: objMemberMetadata.ctor,\n elementTypes: objMemberMetadata.elementType,\n keyType: objMemberMetadata.keyType,\n },\n `${nameof(sourceMeta.classType)}.${objMemberMetadata.key}`,\n objMemberOptions,\n );\n } else {\n throw new TypeError(\n `Could not serialize ${objMemberMetadata.name}, there is`\n + ` no constructor nor serialization function to use.`,\n );\n }\n\n if (isValueDefined(serialized)\n || (this.retrievePreserveNull(objMemberOptions) && serialized === null)\n ) {\n targetObject[objMemberMetadata.name] = serialized;\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 * @param memberOptions If converted as a member, the member options.\n */\n public convertAsArray(\n sourceObject: any[],\n expectedElementType: Function[],\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ): any[] {\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\n // value emitted during serialization. This is so that invalid element types don't unexpectedly\n // 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 (!(this.retrievePreserveNull(memberOptions) && element === null)\n && !isInstanceOf(element, expectedElementType[0])\n ) {\n const expectedTypeName = nameof(expectedElementType[0]);\n const actualTypeName = element && nameof(element.constructor);\n throw new TypeError(`Could not serialize ${memberName}[${i}]:` +\n ` expected '${expectedTypeName}', got '${actualTypeName}'.`);\n }\n });\n\n const typeInfoForElements: IScopeTypeInfo = {\n selfType: expectedElementType[0],\n // For multidimensional arrays.\n elementTypes: expectedElementType.length > 1 ? expectedElementType.slice(1) : [],\n };\n\n if (memberName)\n {\n // Just for debugging purposes.\n memberName += \"[]\";\n }\n\n return sourceObject.map(\n element => this.convertSingleValue(\n element, typeInfoForElements, memberName, memberOptions\n ),\n );\n }\n\n /**\n * Performs the conversion of a set of typed objects (or primitive values) into an array\n * of simple javascript objects.\n *\n * @param sourceObject\n * @param expectedElementType The constructor of the expected Set elements\n * (e.g. `Number` for `Set`, or `MyClass` for `Set`).\n * @param memberName Name of the object being serialized, used for debugging purposes.\n * @param memberOptions If converted as a member, the member options.\n * @returns\n */\n public convertAsSet(\n sourceObject: Set,\n expectedElementType: Function,\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ): any[] {\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.\n // (TODO: clarification needed)\n sourceObject.forEach(element =>\n {\n let resultElement = this.convertSingleValue(element, elementTypeInfo, memberName, memberOptions);\n\n // Add to output if the source element was undefined, OR the converted element is defined.\n // This will add intentionally undefined values to output, but not values that became undefined\n // 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\n * of simple javascript objects with `key` and `value` properties.\n *\n * @param sourceObject\n * @param expectedKeyType The constructor of the expected Map keys\n * (e.g. `Number` for `Map`, or `MyClass` for `Map`).\n * @param expectedElementType The constructor of the expected Map values\n * (e.g. `Number` for `Map`, or `MyClass` for `Map`).\n * @param memberName Name of the object being serialized, used for debugging purposes.\n * @param memberOptions If converted as a member, the member options.\n */\n public convertAsMap(\n sourceObject: Map,\n expectedKeyType: Function,\n expectedElementType: Function,\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ): Array<{ key: any, value: any }> {\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 const resultArray: Array<{ key: any, value: any }> = [];\n const preserveNull = this.retrievePreserveNull(memberOptions);\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, memberOptions),\n value: this.convertSingleValue(value, elementTypeInfo, memberName, memberOptions),\n };\n\n // We are not going to emit entries with undefined keys OR undefined values.\n const keyDefined = isValueDefined(resultKeyValuePairObj.key);\n const valueDefined = isValueDefined(resultKeyValuePairObj.value)\n || (resultKeyValuePairObj.value === null && preserveNull);\n if (keyDefined && valueDefined)\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\n * 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\n * returning that string.\n */\n public convertAsDataView(dataView: DataView)\n {\n return this.convertAsArrayBuffer(dataView.buffer);\n }\n\n private retrievePreserveNull(memberOptions?: OptionsBase): boolean {\n return getOptionValue('preserveNull', mergeOptions(this.options, memberOptions));\n }\n}\n","import { nameof, logError, isSubtypeOf, isValueDefined, isDirectlyDeserializableNativeType } from \"./helpers\";\nimport { Constructor, IndexedObject } from \"./types\";\nimport { JsonObjectMetadata } from \"./metadata\";\nimport { getOptionValue, mergeOptions, OptionsBase } from \"./options-base\";\n\nexport interface IScopeTypeInfo\n{\n selfConstructor: Function;\n elementConstructor?: Function[];\n keyConstructor?: Function;\n knownTypes: Map;\n}\n\nexport type TypeResolver = (sourceObject: Object, knownTypes: Map) => Function|undefined|null;\n\nfunction defaultTypeResolver(sourceObject: any, knownTypes: Map): Function|undefined {\n if (sourceObject.__type) return knownTypes.get(sourceObject.__type);\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 public options?: OptionsBase;\n\n private _typeResolver: TypeResolver = defaultTypeResolver;\n private _nameResolver?: (ctor: Function) => string;\n private _errorHandler: (error: Error) => void = logError;\n\n public setNameResolver(nameResolverCallback: (ctor: Function) => string)\n {\n this._nameResolver = nameResolverCallback;\n }\n\n public setTypeResolver(typeResolverCallback: TypeResolver)\n {\n if (typeof typeResolverCallback !== \"function\")\n {\n throw new TypeError(\"'typeResolverCallback' is not a function.\");\n }\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 memberOptions?: OptionsBase,\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 const 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 const classOptions = mergeOptions(this.options, sourceMetadata.options);\n\n // Deserialize by expected properties.\n sourceMetadata.dataMembers.forEach((objMemberMetadata, propKey) =>\n {\n const objMemberValue = sourceObject[propKey];\n const objMemberDebugName = `${nameof(sourceMetadata.classType)}.${propKey}`;\n const objMemberOptions = mergeOptions(classOptions, objMemberMetadata.options);\n\n let revivedValue;\n if (objMemberMetadata.deserializer) {\n revivedValue = objMemberMetadata.deserializer(objMemberValue);\n } else if (objMemberMetadata.ctor) {\n revivedValue = this.convertSingleValue(\n objMemberValue,\n {\n selfConstructor: objMemberMetadata.ctor,\n elementConstructor: objMemberMetadata.elementType,\n keyConstructor: objMemberMetadata.keyType,\n knownTypes: knownTypeConstructors\n },\n objMemberDebugName,\n objMemberOptions,\n );\n } else {\n throw new TypeError(\n `Cannot deserialize ${objMemberDebugName} there is`\n + ` no constructor nor deserialization function to use.`,\n );\n }\n\n if (isValueDefined(revivedValue)\n || (this.retrievePreserveNull(objMemberOptions) && revivedValue === null)\n ) {\n sourceObjectWithDeserializedProperties[objMemberMetadata.key] = revivedValue;\n }\n else if (objMemberMetadata.isRequired)\n {\n this._errorHandler(new TypeError(`Missing required member '${objMemberDebugName}'.`));\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 // check for member first\n if (typeof (targetObject as any)[sourceObjectMetadata.onDeserializedMethodName] === \"function\")\n {\n (targetObject as any)[sourceObjectMetadata.onDeserializedMethodName]();\n }\n // check for static\n else 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(\n sourceObject: any,\n typeInfo: IScopeTypeInfo,\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ) {\n let expectedSelfType = typeInfo.selfConstructor;\n let srcTypeNameForDebug = sourceObject ? nameof(sourceObject.constructor) : \"undefined\";\n\n if (this.retrievePreserveNull(memberOptions) && sourceObject === null)\n {\n return null;\n }\n else if (!isValueDefined(sourceObject))\n {\n return;\n }\n else if (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 || expectedSelfType === Float64Array)\n {\n // Deserialize Float Array from number[].\n return this._convertAsFloatArray(\n sourceObject,\n expectedSelfType as any,\n srcTypeNameForDebug,\n memberName,\n );\n }\n else if (\n expectedSelfType === Uint8Array\n || expectedSelfType === Uint8ClampedArray\n || expectedSelfType === Uint16Array\n || expectedSelfType === Uint32Array\n ) {\n // Deserialize Uint array from number[].\n return this._convertAsUintArray(\n sourceObject,\n expectedSelfType as any,\n srcTypeNameForDebug,\n memberName,\n );\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 (Array.isArray(sourceObject))\n return this.convertAsArray(sourceObject, typeInfo, memberName, memberOptions);\n else\n throw new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName));\n }\n else if (expectedSelfType === Set)\n {\n if (Array.isArray(sourceObject))\n return this.convertAsSet(sourceObject, typeInfo, memberName, memberOptions);\n else\n this._throwTypeMismatchError(\"Set\", \"Array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Map)\n {\n if (Array.isArray(sourceObject))\n return this.convertAsMap(sourceObject, typeInfo, memberName, memberOptions);\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, memberOptions);\n }\n }\n\n public convertAsArray(\n sourceObject: any,\n typeInfo: IScopeTypeInfo,\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ): any[] {\n if (!(Array.isArray(sourceObject)))\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, `${memberName}[]`, memberOptions);\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(\n sourceObject: any,\n typeInfo: IScopeTypeInfo,\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ): Set {\n if (!(Array.isArray(sourceObject)))\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(\n element,\n elementTypeInfo,\n `${memberName}[${i}]`,\n memberOptions,\n ));\n }\n catch (e)\n {\n // Faulty entries are skipped, because a Set is not ordered, and skipping an entry\n // does not affect others.\n this._errorHandler(e);\n }\n });\n\n return resultSet;\n }\n\n public convertAsMap(\n sourceObject: any,\n typeInfo: IScopeTypeInfo,\n memberName = \"object\",\n memberOptions?: OptionsBase,\n ): Map {\n if (!(Array.isArray(sourceObject)))\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, memberName, memberOptions);\n\n // Undefined/null keys not supported, skip if so.\n if (isValueDefined(key))\n {\n resultMap.set(\n key,\n this.convertSingleValue(\n element.value,\n valueTypeInfo,\n `${memberName}[${key}]`,\n memberOptions,\n ),\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 _convertAsFloatArray(\n sourceObject: any,\n arrayType: Constructor,\n srcTypeNameForDebug: string,\n memberName: string,\n ): T {\n if (Array.isArray(sourceObject) && sourceObject.every(elem => !isNaN(elem)))\n return new arrayType(sourceObject);\n return this._throwTypeMismatchError(\n arrayType.name,\n \"a numeric source array\",\n srcTypeNameForDebug,\n memberName,\n );\n }\n\n private _convertAsUintArray(\n sourceObject: any,\n arrayType: Constructor,\n srcTypeNameForDebug: string,\n memberName: string,\n ): T {\n if (Array.isArray(sourceObject) && sourceObject.every(elem => !isNaN(elem)))\n return new arrayType(sourceObject.map(value => ~~value));\n return this._throwTypeMismatchError(\n arrayType.name,\n \"a numeric source array\",\n srcTypeNameForDebug,\n memberName,\n );\n }\n\n private _throwTypeMismatchError(\n targetType: string,\n expectedSourceType: string,\n actualSourceType: string,\n memberName: string,\n ): never {\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: string)\n {\n const expectedTypeName = (typeof expectedType === \"function\") ? nameof(expectedType) : expectedType;\n const 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 _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 private retrievePreserveNull(memberOptions?: OptionsBase): boolean {\n return getOptionValue('preserveNull', mergeOptions(this.options, memberOptions));\n }\n}\n","import { Constructor } from \"./typedjson/types\";\nimport { Serializer, TypeHintEmitter } from \"./typedjson/serializer\";\nimport { Deserializer, TypeResolver } from \"./typedjson/deserializer\";\nimport { JsonObjectMetadata } from \"./typedjson/metadata\";\nimport { logError, logWarning, nameof, parseToJSObject } from \"./typedjson/helpers\";\nimport { extractOptionBase, OptionsBase } from \"./typedjson/options-base\";\n\nexport type JsonTypes = Object|boolean|string|number|null|undefined;\nexport { TypeResolver, TypeHintEmitter };\n\nexport interface ITypedJSONSettings extends OptionsBase\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?: TypeResolver;\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?: TypeHintEmitter;\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 ): Object[]|undefined {\n return new TypedJSON(elementType, settings).toPlainSet(object);\n }\n\n public static toPlainMap(\n object: Map,\n keyCtor: Constructor,\n valueCtor: Constructor,\n settings?: ITypedJSONSettings,\n ): { key: any, value: any }[]|undefined {\n return new TypedJSON(valueCtor, settings).toPlainMap(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 const options = extractOptionBase(settings);\n this.serializer.options = options;\n this.deserializer.options = options;\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(\n 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\";\nimport { extractOptionBase, OptionsBase } from \"./options-base\";\n\nexport type InitializerCallback = (sourceObject: T, rawSourceObject: T) => T;\n\nexport interface IJsonObjectOptionsBase extends OptionsBase\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 of a static or instance method to call before the serialization\n * of the typed object is started.\n */\n beforeSerialization?: 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 * Function to call before deserializing and initializing the object, accepting two arguments:\n * (1) sourceObject, an 'Object' instance with all properties already deserialized, and\n * (2) rawSourceObject, a raw 'Object' instance representation of the current object in\n * the serialized JSON (i.e. without deserialized properties).\n */\n initializer: InitializerCallback;\n}\n\nexport interface IJsonObjectOptions extends IJsonObjectOptionsBase\n{\n /**\n * Function to call before deserializing and initializing the object, accepting two arguments:\n * (1) sourceObject, an 'Object' instance with all properties already deserialized, and\n * (2) rawSourceObject, a raw 'Object' instance representation of the current object in\n * the serialized JSON (i.e. without deserialized properties).\n */\n initializer?: InitializerCallback;\n}\n\n/**\n * Marks that a class with a parameterized constructor is serializable using TypedJSON, with additional\n * 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 objectMetadata.beforeSerializationMethodName = options.beforeSerialization;\n \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 const optionsBase = extractOptionBase(options);\n if (optionsBase)\n {\n objectMetadata.options = optionsBase;\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, MISSING_REFLECT_CONF_MSG,\n} from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\nimport { extractOptionBase, OptionsBase } from \"./options-base\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonMemberOptions extends OptionsBase\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. ${MISSING_REFLECT_CONF_MSG}`);\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,\n isRequired: options.isRequired,\n options: extractOptionBase(options),\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, MISSING_REFLECT_CONF_MSG } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\nimport { extractOptionBase, OptionsBase } from \"./options-base\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonArrayMemberOptions extends OptionsBase\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. ${MISSING_REFLECT_CONF_MSG}`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Array,\n elementType: createArrayElementType(elementConstructor, dimensions),\n emitDefaultValue: options.emitDefaultValue,\n isRequired: options.isRequired,\n options: extractOptionBase(options),\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 { isReflectMetadataSupported, logError, MISSING_REFLECT_CONF_MSG, nameof } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\nimport { extractOptionBase, OptionsBase } from \"./options-base\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonSetMemberOptions extends OptionsBase\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 const decoratorName = `@jsonSetMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof elementConstructor !== \"function\")\n {\n 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 (isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Set)\n {\n logError(`${decoratorName}: property is not a Set. ${MISSING_REFLECT_CONF_MSG}`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Set,\n elementType: [elementConstructor],\n emitDefaultValue: options.emitDefaultValue,\n isRequired: options.isRequired,\n options: extractOptionBase(options),\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, MISSING_REFLECT_CONF_MSG } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\nimport { extractOptionBase, OptionsBase } from \"./options-base\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonMapMemberOptions extends OptionsBase\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. ${MISSING_REFLECT_CONF_MSG}`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Map,\n elementType: [valueConstructor],\n keyType: keyConstructor,\n emitDefaultValue: options.emitDefaultValue,\n isRequired: options.isRequired,\n options: extractOptionBase(options),\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n","import { TypedJSON } from \"../parser\";\n\n/**\n * Options for the @toJson decorator.\n */\nexport interface IToJsonOptions {\n /**\n * When set to true it will overwrite any toJSON already existing on the prototype.\n */\n overwrite?: boolean;\n}\n\n/**\n * Decorator that will generate toJSON function on the class prototype that allows\n * JSON.stringify to be used instead of TypedJSON.stringify. Under the hood it will\n * simply delegate to TypedJSON.\n * By default it will throw if the prototype already has a toJSON function defined.\n * @param target the class which prototype should be modified.\n */\nexport function toJson(target: Function): void;\n/**\n * Decorator factory that accepts the options interface.\n * @param options for configuring the toJSON creation.\n */\nexport function toJson(options: IToJsonOptions): ((target: Function) => void);\nexport function toJson(optionsOrTarget: IToJsonOptions | Function\n): ((target: Function) => void) | void {\n if (typeof optionsOrTarget === 'function') {\n // used directly\n toJsonDecorator(optionsOrTarget, {});\n return;\n }\n // used as a factory\n return (target: Function) => {\n toJsonDecorator(target, optionsOrTarget);\n }\n}\n\nfunction toJsonDecorator(target: Function, options: IToJsonOptions): void {\n if (!options.overwrite && target.prototype.toJSON) {\n throw new Error(`${target.name} already has toJSON defined!`);\n }\n target.prototype.toJSON = function () {\n return TypedJSON.toPlainJson(this, Object.getPrototypeOf(this).constructor);\n }\n}\n","export { TypedJSON, ITypedJSONSettings, JsonTypes, TypeResolver, TypeHintEmitter } 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\";\nexport { toJson } from \"./typedjson/to-json\";\n"],"sourceRoot":""} \ No newline at end of file diff --git a/js/typedjson/deserializer.d.ts b/js/typedjson/deserializer.d.ts deleted file mode 100644 index 5de62ee..0000000 --- a/js/typedjson/deserializer.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { IndexedObject } from "./types"; -import { OptionsBase } from "./options-base"; -export interface IScopeTypeInfo { - selfConstructor: Function; - elementConstructor?: Function[]; - keyConstructor?: Function; - knownTypes: Map; -} -export declare type TypeResolver = (sourceObject: Object, knownTypes: Map) => Function | undefined | null; -/** - * Utility class, converts a simple/untyped javascript object-tree to a typed object-tree. - * It is used after parsing a JSON-string. - */ -export declare class Deserializer { - options?: OptionsBase; - private _typeResolver; - private _nameResolver?; - private _errorHandler; - setNameResolver(nameResolverCallback: (ctor: Function) => string): void; - setTypeResolver(typeResolverCallback: TypeResolver): void; - setErrorHandler(errorHandlerCallback: (error: Error) => void): void; - convertAsObject(sourceObject: IndexedObject, sourceObjectTypeInfo: IScopeTypeInfo, objectName?: string, memberOptions?: OptionsBase): {} | undefined; - convertSingleValue(sourceObject: any, typeInfo: IScopeTypeInfo, memberName?: string, memberOptions?: OptionsBase): any; - convertAsArray(sourceObject: any, typeInfo: IScopeTypeInfo, memberName?: string, memberOptions?: OptionsBase): any[]; - convertAsSet(sourceObject: any, typeInfo: IScopeTypeInfo, memberName?: string, memberOptions?: OptionsBase): Set; - convertAsMap(sourceObject: any, typeInfo: IScopeTypeInfo, memberName?: string, memberOptions?: OptionsBase): Map; - private _convertAsFloatArray; - private _convertAsUintArray; - private _throwTypeMismatchError; - private _makeTypeErrorMessage; - private _instantiateType; - private _mergeKnownTypes; - private _createKnownTypesMap; - private _stringToArrayBuffer; - private _stringToDataView; - private retrievePreserveNull; -} diff --git a/js/typedjson/helpers.d.ts b/js/typedjson/helpers.d.ts deleted file mode 100644 index 2a8b605..0000000 --- a/js/typedjson/helpers.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -export declare const METADATA_FIELD_KEY = "__typedJsonJsonObjectMetadataInformation__"; -export declare const MISSING_REFLECT_CONF_MSG: string; -export declare function getDefaultValue(type: { - new (): T; -}): T | undefined; -/** - * Determines whether the specified type is a type that can be passed on "as-is" into `JSON.stringify`. - * Values of these types don't need special conversion. - * @param type The constructor of the type (wrapper constructor for primitive types, e.g. `Number` for `number`). - */ -export declare function isDirectlySerializableNativeType(type: Function): boolean; -export declare function isDirectlyDeserializableNativeType(type: Function): boolean; -export declare function isTypeTypedArray(type: Function): boolean; -export declare function isPrimitiveValue(obj: any): boolean; -export declare function isObject(value: any): value is Object; -export declare function parseToJSObject(json: any, expectedType: Function): Object; -/** - * Determines if 'A' is a sub-type of 'B' (or if 'A' equals 'B'). - * @param A The supposed derived type. - * @param B The supposed base type. - */ -export declare function isSubtypeOf(A: Function, B: Function): boolean; -export declare function logError(message?: any, ...optionalParams: any[]): void; -export declare function logMessage(message?: any, ...optionalParams: any[]): void; -export declare function logWarning(message?: any, ...optionalParams: any[]): void; -/** - * Checks if the value is considered defined (not undefined and not null). - * @param value - */ -export declare function isValueDefined(value: T): value is Exclude; -export declare function isInstanceOf(value: any, constructor: Function): boolean; -export declare const isReflectMetadataSupported: boolean; -/** - * Gets the name of a function. - * @param fn The function whose name to get. - */ -export declare function nameof(fn: Function & { - name?: string; -}): string; diff --git a/js/typedjson/json-array-member.d.ts b/js/typedjson/json-array-member.d.ts deleted file mode 100644 index 83d9ade..0000000 --- a/js/typedjson/json-array-member.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { OptionsBase } from "./options-base"; -export interface IJsonArrayMemberOptions extends OptionsBase { - /** When set, indicates that the member must be present when deserializing. */ - isRequired?: boolean; - /** When set, an empty array is emitted if the property is undefined/uninitialized. */ - emitDefaultValue?: boolean; - /** Sets array dimensions (e.g. 1 for 'number[]' or 2 for 'number[][]'). Defaults to 1. */ - dimensions?: number; - /** When set, the key on the JSON that should be used instead of the class property name */ - name?: string; - /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */ - deserializer?: (json: any) => any; - /** When set, this serializer will be used to serialize the member. */ - serializer?: (value: any) => any; -} -/** - * 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. - */ -export declare function jsonArrayMember(elementConstructor: Function, options?: IJsonArrayMemberOptions): (target: Object, propKey: string | symbol) => void; diff --git a/js/typedjson/json-map-member.d.ts b/js/typedjson/json-map-member.d.ts deleted file mode 100644 index a3996de..0000000 --- a/js/typedjson/json-map-member.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { OptionsBase } from "./options-base"; -export interface IJsonMapMemberOptions extends OptionsBase { - /** When set, indicates that the member must be present when deserializing. */ - isRequired?: boolean; - /** When set, a default value is emitted for each uninitialized json member. */ - emitDefaultValue?: boolean; - /** When set, the key on the JSON that should be used instead of the class property name */ - name?: string; - /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */ - deserializer?: (json: any) => any; - /** When set, this serializer will be used to serialize the member. */ - serializer?: (value: any) => any; -} -/** - * 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. - */ -export declare function jsonMapMember(keyConstructor: Function, valueConstructor: Function, options?: IJsonMapMemberOptions): (target: Object, propKey: string | symbol) => void; diff --git a/js/typedjson/json-member.d.ts b/js/typedjson/json-member.d.ts deleted file mode 100644 index 985838d..0000000 --- a/js/typedjson/json-member.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { OptionsBase } from "./options-base"; -export interface IJsonMemberOptions extends OptionsBase { - /** - * Sets the constructor of the property. - * Optional with ReflectDecorators. - */ - constructor?: Function; - /** When set, indicates that the member must be present when deserializing. */ - isRequired?: boolean; - /** When set, a default value is emitted if the property is uninitialized/undefined. */ - emitDefaultValue?: boolean; - /** When set, the key on the JSON that should be used instead of the class property name. */ - name?: string; - /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */ - deserializer?: (json: any) => any; - /** When set, this serializer will be used to serialize the member. */ - serializer?: (value: any) => any; -} -/** - * Specifies that a property is part of the object when serializing, with additional options. - * Omitting the 'constructor' option requires ReflectDecorators and that the property type is always explicitly declared. - * @param options Additional options. - */ -export declare function jsonMember(options: IJsonMemberOptions): PropertyDecorator; -/** - * Specifies that a property is part of the object when serializing. - * This call signature requires ReflectDecorators and that the property type is always explicitly declared. - */ -export declare function jsonMember(target: Object, propertyKey: string | symbol): void; diff --git a/js/typedjson/json-object.d.ts b/js/typedjson/json-object.d.ts deleted file mode 100644 index 7da0b64..0000000 --- a/js/typedjson/json-object.d.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Constructor, ParameterlessConstructor } from "./types"; -import { OptionsBase } from "./options-base"; -export declare type InitializerCallback = (sourceObject: T, rawSourceObject: T) => T; -export interface IJsonObjectOptionsBase extends OptionsBase { - /** - * An array of known types to recognize when encountering type-hints, - * or the name of a static method used for determining known types. - */ - knownTypes?: Function[] | string; - /** - * The name of a static or instance method to call when deserialization - * of the object is completed. - */ - onDeserialized?: string; - /** - * The name of a static or instance method to call before the serialization - * of the typed object is started. - */ - beforeSerialization?: string; - /** - * The name used to differentiate between different polymorphic types. - */ - name?: string; -} -export interface IJsonObjectOptionsWithInitializer extends IJsonObjectOptionsBase { - /** - * Function to call before deserializing and initializing the object, accepting two arguments: - * (1) sourceObject, an 'Object' instance with all properties already deserialized, and - * (2) rawSourceObject, a raw 'Object' instance representation of the current object in - * the serialized JSON (i.e. without deserialized properties). - */ - initializer: InitializerCallback; -} -export interface IJsonObjectOptions extends IJsonObjectOptionsBase { - /** - * Function to call before deserializing and initializing the object, accepting two arguments: - * (1) sourceObject, an 'Object' instance with all properties already deserialized, and - * (2) rawSourceObject, a raw 'Object' instance representation of the current object in - * the serialized JSON (i.e. without deserialized properties). - */ - initializer?: InitializerCallback; -} -/** - * Marks that a class with a parameterized constructor is serializable using TypedJSON, with additional - * settings. The 'initializer' setting must be specified. - * @param options Configuration settings. - */ -export declare function jsonObject(options?: IJsonObjectOptionsWithInitializer): (target: Constructor) => void; -/** - * Marks that a class is serializable using TypedJSON, with additional settings. - * @param options Configuration settings. - */ -export declare function jsonObject(options?: IJsonObjectOptions): (target: ParameterlessConstructor) => void; -/** - * Marks that a class with a parameterless constructor is serializable using TypedJSON. - */ -export declare function jsonObject(target: ParameterlessConstructor): void; diff --git a/js/typedjson/json-set-member.d.ts b/js/typedjson/json-set-member.d.ts deleted file mode 100644 index 5612b80..0000000 --- a/js/typedjson/json-set-member.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { OptionsBase } from "./options-base"; -export interface IJsonSetMemberOptions extends OptionsBase { - /** When set, indicates that the member must be present when deserializing. */ - isRequired?: boolean; - /** When set, a default value is emitted for each uninitialized json member. */ - emitDefaultValue?: boolean; - /** When set, the key on the JSON that should be used instead of the class property name */ - name?: string; - /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */ - deserializer?: (json: any) => any; - /** When set, this serializer will be used to serialize the member. */ - serializer?: (value: any) => any; -} -/** - * 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. - */ -export declare function jsonSetMember(elementConstructor: Function, options?: IJsonSetMemberOptions): (target: Object, propKey: string | symbol) => void; diff --git a/js/typedjson/metadata.d.ts b/js/typedjson/metadata.d.ts deleted file mode 100644 index f6adc34..0000000 --- a/js/typedjson/metadata.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { IndexedObject } from "./types"; -import { OptionsBase } from "./options-base"; -export interface JsonMemberMetadata { - /** If set, a default value will be emitted for uninitialized members. */ - emitDefaultValue?: boolean; - /** Member name as it appears in the serialized JSON. */ - name: string; - /** Property or field key of the json member. */ - key: string; - /** Constuctor (type) reference of the member. */ - ctor?: Function; - /** If set, indicates that the member must be present when deserializing. */ - isRequired?: boolean; - options?: OptionsBase; - /** If the json member is an array, map or set, sets member options of elements/values. Subsequent values define the types of nested arrays. */ - elementType?: Function[]; - /** If the json member is a map, sets member options of array keys. */ - keyType?: Function; - /** Custom deserializer to use. */ - deserializer?: (json: any) => any; - /** Custom serializer to use. */ - serializer?: (value: any) => any; -} -export declare class JsonObjectMetadata { - /** - * Gets the name of a class as it appears in a serialized JSON string. - * @param ctor The constructor of a class (with or without jsonObject). - */ - static getJsonObjectName(ctor: Function): string; - /** - * Gets jsonObject metadata information from a class. - * @param ctor The constructor class. - */ - static getFromConstructor(ctor: Function): JsonObjectMetadata | undefined; - /** - * Gets the known type name of a jsonObject class for type hint. - * @param constructor The constructor class. - */ - static getKnownTypeNameFromType(constructor: Function): string; - private static doesHandleWithoutAnnotation; - constructor(classType: Function); - dataMembers: Map; - knownTypes: Set; - knownTypeMethodName?: string; - /** Gets or sets the constructor function for the jsonObject. */ - classType: Function; - /** - * Indicates whether this class was explicitly annotated with @jsonObject - * or implicitly by @jsonMember - */ - isExplicitlyMarked: boolean; - /** - * Indicates whether this type is handled without annotation. This is usually - * used for the builtin types (except for Maps, Sets, and normal Arrays). - */ - isHandledWithoutAnnotation: boolean; - /** Name used to encode polymorphic type */ - name?: string; - options?: OptionsBase; - onDeserializedMethodName?: string; - beforeSerializationMethodName?: string; - initializerCallback?: (sourceObject: Object, rawSourceObject: Object) => Object; -} -export declare function injectMetadataInformation(constructor: IndexedObject, propKey: string | symbol, metadata: JsonMemberMetadata): void; diff --git a/js/typedjson/options-base.d.ts b/js/typedjson/options-base.d.ts deleted file mode 100644 index 159cf53..0000000 --- a/js/typedjson/options-base.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * This options cascade through the annotations. Options set - * in the more specific place override the previous option. - * Ex. @jsonMember overrides TypedJson options. - */ -export interface OptionsBase { - /** - * Whether to preserve null in the JSON output. When false it - * will not emit nor store the property if its value is null. - * Default: false. - */ - preserveNull?: boolean; -} -export declare function extractOptionBase(from: { - [key: string]: any; -} & OptionsBase): OptionsBase | undefined; -export declare function getDefaultOptionOf(key: K): Required[K]; -export declare function getOptionValue(key: K, options?: OptionsBase): Required[K]; -export declare function mergeOptions(existing?: OptionsBase, moreSpecific?: OptionsBase): OptionsBase | undefined; diff --git a/js/typedjson/serializer.d.ts b/js/typedjson/serializer.d.ts deleted file mode 100644 index 2208d4a..0000000 --- a/js/typedjson/serializer.d.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { IndexedObject } from "./types"; -import { JsonObjectMetadata } from "./metadata"; -import { OptionsBase } from "./options-base"; -export interface IScopeTypeInfo { - selfType: Function; - elementTypes?: Function[]; - keyType?: Function; -} -export interface IScopeArrayTypeInfo extends IScopeTypeInfo { - selfType: new () => Array; - elementTypes: Function[]; -} -export interface IScopeSetTypeInfo extends IScopeTypeInfo { - selfType: new () => Set; - elementTypes: [Function]; -} -export interface IScopeMapTypeInfo extends IScopeTypeInfo { - selfType: new () => Map; - elementTypes: [Function]; - keyType: Function; -} -export declare type TypeHintEmitter = (targetObject: IndexedObject, sourceObject: IndexedObject, expectedSourceType: Function, sourceTypeMetadata?: JsonObjectMetadata) => void; -/** - * 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 - */ -export declare class Serializer { - options?: OptionsBase; - private _typeHintEmitter; - private _errorHandler; - setTypeHintEmitter(typeEmitterCallback: TypeHintEmitter): void; - setErrorHandler(errorHandlerCallback: (error: Error) => void): void; - /** - * Convert a value of any supported serializable type. - * The value type will be detected, and the correct serialization method will be called. - */ - convertSingleValue(sourceObject: any, typeInfo: IScopeTypeInfo, memberName?: string, memberOptions?: OptionsBase): any; - /** - * Performs the conversion of a typed object (usually a class instance) to a simple - * javascript object for serialization. - */ - convertAsObject(sourceObject: IndexedObject, typeInfo: IScopeTypeInfo, memberName?: string, memberOptions?: OptionsBase): IndexedObject; - /** - * 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. - * @param memberOptions If converted as a member, the member options. - */ - convertAsArray(sourceObject: any[], expectedElementType: Function[], memberName?: string, memberOptions?: OptionsBase): any[]; - /** - * 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. - * @param memberOptions If converted as a member, the member options. - * @returns - */ - convertAsSet(sourceObject: Set, expectedElementType: Function, memberName?: string, memberOptions?: OptionsBase): any[]; - /** - * 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. - * @param memberOptions If converted as a member, the member options. - */ - convertAsMap(sourceObject: Map, expectedKeyType: Function, expectedElementType: Function, memberName?: string, memberOptions?: OptionsBase): Array<{ - key: any; - value: any; - }>; - /** - * 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 - */ - convertAsTypedArray(sourceObject: ArrayBufferView): unknown[]; - /** - * Performs the conversion of a raw ArrayBuffer to a string. - */ - convertAsArrayBuffer(buffer: ArrayBuffer): string; - /** - * Performs the conversion of DataView, converting its internal ArrayBuffer to a string and - * returning that string. - */ - convertAsDataView(dataView: DataView): string; - private retrievePreserveNull; -} diff --git a/js/typedjson/to-json.d.ts b/js/typedjson/to-json.d.ts deleted file mode 100644 index e989a8d..0000000 --- a/js/typedjson/to-json.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Options for the @toJson decorator. - */ -export interface IToJsonOptions { - /** - * When set to true it will overwrite any toJSON already existing on the prototype. - */ - overwrite?: boolean; -} -/** - * Decorator that will generate toJSON function on the class prototype that allows - * JSON.stringify to be used instead of TypedJSON.stringify. Under the hood it will - * simply delegate to TypedJSON. - * By default it will throw if the prototype already has a toJSON function defined. - * @param target the class which prototype should be modified. - */ -export declare function toJson(target: Function): void; -/** - * Decorator factory that accepts the options interface. - * @param options for configuring the toJSON creation. - */ -export declare function toJson(options: IToJsonOptions): ((target: Function) => void); diff --git a/js/typedjson/types.d.ts b/js/typedjson/types.d.ts deleted file mode 100644 index a2cdb45..0000000 --- a/js/typedjson/types.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export declare type IndexedObject = Object & { - [key: string]: any; -}; -export declare type Constructor = new (...args: any[]) => T; -export declare type ParameterlessConstructor = new () => T; diff --git a/lint-staged.config.js b/lint-staged.config.js new file mode 100644 index 0000000..6f9949a --- /dev/null +++ b/lint-staged.config.js @@ -0,0 +1,13 @@ +function mapFilenames(filenames) { + return filenames.map(filename => `"${filename}"`).join(' '); +} + +module.exports = { + '*': () => [ + 'yarn run test', + 'yarn run test:ts', + ], + '*.ts': (filenames) => [ + `eslint --fix --cache ${mapFilenames(filenames)}`, + ], +}; diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 6ee3e1b..0000000 --- a/package-lock.json +++ /dev/null @@ -1,5856 +0,0 @@ -{ - "name": "typedjson", - "version": "1.5.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/core": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz", - "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.4", - "@babel/helpers": "^7.8.4", - "@babel/parser": "^7.8.4", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.4", - "@babel/types": "^7.8.3", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", - "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helpers": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", - "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", - "dev": true, - "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.4", - "@babel/types": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", - "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", - "dev": true - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/traverse": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", - "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.4", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.4", - "@babel/types": "^7.8.3", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", - "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "@istanbuljs/load-nyc-config": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", - "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - } - }, - "@istanbuljs/nyc-config-typescript": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@istanbuljs/nyc-config-typescript/-/nyc-config-typescript-1.0.1.tgz", - "integrity": "sha512-/gz6LgVpky205LuoOfwEZmnUtaSmdk0QIMcNFj9OvxhiMhPpKftMgZmGN7jNj7jR+lr8IB1Yks3QSSSNSxfoaQ==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2" - } - }, - "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", - "dev": true - }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, - "@types/jasmine": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.5.3.tgz", - "integrity": "sha512-LRJ21f/BO4QNZ3YDaMP0OEurOfE77x8mi8MfEnUsei5IKfmZL0GKl7juhABMdUIJHhVS9OCLotKHfsFNAuJ+DA==", - "dev": true - }, - "@webassemblyjs/ast": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", - "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", - "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", - "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", - "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", - "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", - "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", - "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "mamacro": "^0.0.3" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", - "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", - "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", - "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", - "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", - "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", - "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/helper-wasm-section": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-opt": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", - "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", - "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", - "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", - "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/floating-point-hex-parser": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-code-frame": "1.8.5", - "@webassemblyjs/helper-fsm": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", - "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "acorn": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", - "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", - "dev": true - }, - "aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", - "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "requires": { - "default-require-extensions": "^3.0.0" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", - "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "requires": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "chownr": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", - "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", - "dev": true, - "requires": { - "strip-bom": "^4.0.0" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "elliptic": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", - "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "figgy-pudding": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-cache-dir": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.2.0.tgz", - "integrity": "sha512-1JKclkYYsf1q9WIJKLZa9S9muC+08RIjzAlLrK4QcYLJMS6mk9yombQ9qf+zJ7H9LS800k0s44L4sDq9VYzqyg==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.0", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fromentries": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.0.tgz", - "integrity": "sha512-33X7H/wdfO99GdRLLgkjUrD4geAFdq/Uv0kl3HD4da6HDixd2GUg8Mw7dahLCV9r/EARkmtYBB6Tch4EEokFTQ==", - "dev": true - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", - "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1", - "node-pre-gyp": "*" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.13", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "3.1.1", - "bundled": true, - "dev": true - } - } - }, - "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "requires": { - "global-prefix": "^3.0.0" - }, - "dependencies": { - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hasha": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.1.0.tgz", - "integrity": "sha512-OFPDWmzPN1l7atOV1TgBVmNtBxaIysToK6Ve9DK+vT6pYuklw/nPNT+HJbZi0KDcI6vWB+9tgvZ5YD7fA3CXcA==", - "dev": true, - "requires": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "html-escaper": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz", - "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==", - "dev": true - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "dev": true, - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - } - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, - "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", - "dev": true - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "dev": true - }, - "istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "requires": { - "append-transform": "^2.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz", - "integrity": "sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg==", - "dev": true, - "requires": { - "@babel/core": "^7.7.5", - "@babel/parser": "^7.7.5", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - } - }, - "istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^3.3.3" - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jasmine": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.5.0.tgz", - "integrity": "sha512-DYypSryORqzsGoMazemIHUfMkXM7I7easFaxAvNM3Mr6Xz3Fy36TupTrAOxZWN8MVKEU5xECv22J4tUQf3uBzQ==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "jasmine-core": "~3.5.0" - } - }, - "jasmine-core": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.5.0.tgz", - "integrity": "sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json5": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", - "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", - "dev": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz", - "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "mamacro": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", - "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", - "dev": true - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "requires": { - "process-on-spawn": "^1.0.0" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - }, - "dependencies": { - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - } - } - }, - "nyc": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.0.0.tgz", - "integrity": "sha512-qcLBlNCKMDVuKb7d1fpxjPR8sHeMVX0CHarXAVzrVWoFrigCkYR8xcrjfXSPi5HXM7EU78L6ywO7w1c5rZNCNg==", - "dev": true, - "requires": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.0", - "js-yaml": "^3.13.1", - "make-dir": "^3.0.0", - "node-preload": "^0.2.0", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "uuid": "^3.3.3", - "yargs": "^15.0.2" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "picomatch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", - "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "requires": { - "fromentries": "^1.2.0" - } - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", - "dev": true - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "requires": { - "es6-error": "^4.0.1" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - } - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "dependencies": { - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - } - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "serialize-javascript": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", - "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "requires": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "terser": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.3.tgz", - "integrity": "sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^2.1.2", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "dependencies": { - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "ts-loader": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.1.tgz", - "integrity": "sha512-Dd9FekWuABGgjE1g0TlQJ+4dFUfYGbYcs52/HQObE0ZmUNjQlmLAS7xXsSzy23AMaMwipsx5sNHvoEpT2CZq1g==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^4.0.0", - "semver": "^6.0.0" - } - }, - "ts-node": { - "version": "8.6.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.6.2.tgz", - "integrity": "sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==", - "dev": true, - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "3.1.1" - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", - "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", - "dev": true - }, - "uglify-js": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.7.tgz", - "integrity": "sha512-FeSU+hi7ULYy6mn8PKio/tXsdSXN35lm4KgV2asx00kzrLU9Pi3oAslcJT70Jdj7PHX29gGUPOT6+lXGBbemhA==", - "dev": true, - "requires": { - "commander": "~2.20.3", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "uglifyjs-webpack-plugin": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-2.2.0.tgz", - "integrity": "sha512-mHSkufBmBuJ+KHQhv5H0MXijtsoA1lynJt1lXOaotja8/I0pR4L9oGaPIZw+bQBOFittXZg9OC1sXSGO9D9ZYg==", - "dev": true, - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^1.7.0", - "source-map": "^0.6.1", - "uglify-js": "^3.6.0", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "dependencies": { - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - }, - "v8-compile-cache": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", - "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", - "dev": true - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", - "dev": true, - "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - } - }, - "webpack": { - "version": "4.41.5", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.5.tgz", - "integrity": "sha512-wp0Co4vpyumnp3KlkmpM5LWuzvZYayDwM2n17EHFr4qxBBbRokC7DJawPJC7TfSFZ9HZ6GsdH40EBj4UV0nmpw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/wasm-edit": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "acorn": "^6.2.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.1", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.6.0", - "webpack-sources": "^1.4.1" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "webpack-auto-inject-version": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/webpack-auto-inject-version/-/webpack-auto-inject-version-1.2.2.tgz", - "integrity": "sha512-duFSWzZe/OY8zyr2DpymzZeY8yI1RSZ9hu9wDwZy/fhxwntgpEzTwyIB/U7ig+FB26mif8xx5zS1E3Co9c5cYA==", - "dev": true - }, - "webpack-cli": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.10.tgz", - "integrity": "sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg==", - "dev": true, - "requires": { - "chalk": "2.4.2", - "cross-spawn": "6.0.5", - "enhanced-resolve": "4.1.0", - "findup-sync": "3.0.0", - "global-modules": "2.0.0", - "import-local": "2.0.0", - "interpret": "1.2.0", - "loader-utils": "1.2.3", - "supports-color": "6.1.0", - "v8-compile-cache": "2.0.3", - "yargs": "13.2.4" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "enhanced-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", - "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.4.0", - "tapable": "^1.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "13.2.4", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", - "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.0" - } - }, - "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz", - "integrity": "sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yargs": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz", - "integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^16.1.0" - } - }, - "yargs-parser": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", - "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - } - } -} diff --git a/package.json b/package.json index 2dccda0..b40bca8 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,33 @@ { "name": "typedjson", - "version": "1.5.1", + "version": "1.8.0", "description": "Typed JSON parsing and serializing for TypeScript that preserves type information, using decorators. Parse JSON into actual class instances.", - "main": "./js/typedjson.js", - "typings": "./js/typedjson.d.ts", + "main": "./lib/cjs/index.js", + "module": "./lib/esm5/index.js", + "es2015": "./lib/esm/index.js", + "types": "./lib/types/index.d.ts", + "sideEffects": false, + "size-limit": [ + { + "path": "./lib/esm/index.js", + "limit": "8 KB" + } + ], "scripts": { - "test": "npm run build && nyc ts-node -O '{\"module\": \"commonjs\", \"strict\": false}' node_modules/jasmine/bin/jasmine.js", - "build": "webpack", - "preversion": "npm test", - "version": "npm run build && git add -A js" + "build": "run-s build:*", + "build:clean": "rimraf ./lib", + "build:ts": "tsc --build ./tsconfig/tsconfig.bundle.*.json", + "coverage": "nyc yarn run test", + "lint": "eslint \"spec/**/*.ts\" \"src/**/*.ts\"", + "preversion": "yarn run coverage", + "size": "size-limit", + "test": "yarn run test:base node_modules/jasmine/bin/jasmine.js", + "test:base": "TS_NODE_PROJECT=tsconfig/tsconfig.spec.json node -r ts-node/register", + "test:inspect": "yarn run test:base --inspect-brk node_modules/jasmine/bin/jasmine.js", + "test:ts": "run-p test:ts:*", + "test:ts:src": "tsc -p tsconfig/tsconfig.app-strict.json", + "test:ts:spec": "tsc -p tsconfig/tsconfig.spec-strict.json", + "version": "yarn run build" }, "repository": { "type": "git", @@ -20,19 +39,33 @@ "url": "https://github.com/JohnWhiteTB/TypedJSON/issues" }, "homepage": "https://github.com/JohnWhiteTB/TypedJSON", + "dependencies": { + "tslib": "^2.0.1" + }, "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.1", + "@matthiaskunnen/eslint-config-typescript": "^1.2.0", + "@size-limit/preset-small-lib": "^4.5.7", "@types/jasmine": "^3.5.3", + "eslint-plugin-jasmine": "^4.1.1", + "husky": "^4.2.5", "jasmine": "^3.5.0", + "lint-staged": "^10.2.13", + "npm-run-all": "^4.1.5", "nyc": "^15.0.0", "reflect-metadata": "^0.1.13", - "source-map-support": "^0.5.16", - "ts-loader": "^6.2.1", - "ts-node": "^8.6.2", - "typescript": "^3.7.5", - "uglifyjs-webpack-plugin": "^2.2.0", - "webpack": "^4.41.5", - "webpack-auto-inject-version": "^1.2.2", - "webpack-cli": "^3.3.10" - } + "rimraf": "^3.0.2", + "size-limit": "^4.5.7", + "ts-node": "^8.10.2", + "typescript": "^3.9.7" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "files": [ + "lib/**/!(*.tsbuildinfo)", + "src" + ] } diff --git a/readme.md b/readme.md index 4bc4672..1f7ae13 100644 --- a/readme.md +++ b/readme.md @@ -1,10 +1,14 @@ -[![Build Status](https://github.com/JohnWeisz/TypedJSON/workflows/Node%20CI/badge.svg)](https://github.com/JohnWeisz/TypedJSON/actions) +[![npm version](https://img.shields.io/npm/v/typedjson.svg?logo=npm&style=for-the-badge)](https://www.npmjs.com/package/typedjson) +[![Build Status](https://img.shields.io/github/workflow/status/JohnWeisz/TypedJSON/Node%20CI?label=CI&logo=github&style=for-the-badge) +](https://github.com/JohnWeisz/TypedJSON/actions) +[![Build Status](https://img.shields.io/npm/l/typedjson?&style=for-the-badge&color=green) +](https://github.com/JohnWeisz/typedjson/blob/master/LICENSE) Typed JSON parsing and serializing for TypeScript with [decorators](https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md). Annotate your data-classes with simple-to-use decorators and parse standard JSON into actual class instances. For more type-safety and less syntax, recommended to be used with [reflect-metadata](https://github.com/rbuckton/reflect-metadata), a prototype for an ES7 Reflection API for Decorator Metadata. - Seamlessly integrate into existing code with [decorators](https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md), ultra-lightweight syntax - Parse standard JSON to typed class instances, safely, without requiring any type-information to be specified in the source JSON - - _Note: polymorphic object structures require simple type-annotations to be present in JSON, this is configurable to be complatible with other serializers, like [Json.NET](https://www.newtonsoft.com/json)_ + - _Note: polymorphic object structures require simple type-annotations to be present in JSON, this is configurable to be compatible with other serializers, like [Json.NET](https://www.newtonsoft.com/json)_ ## Installation @@ -63,6 +67,47 @@ const object3 = serializer.parse('{ "prop1": 1, "prop2": "2" }'); object3 instanceof MyDataClass; // true ``` +Note TypedJSON supports parsing arrays and maps at root level as well. Those methods are defined in [parser.ts](https://github.com/JohnWeisz/TypedJSON/blob/master/src/parser.ts). Here is an example showing how to parse a json array: +```typescript +const object4 = serializer.parseAsArray('[{ "prop1": 1, "prop2": "2" }]'); +object4; // [ MyDataClass { prop1: 1, prop2: '2' } ] +``` + +### Mapping types + +At times, you might find yourself using a custom type such as `Point`, `Decimal`, or `BigInt`. In this case, `TypedJSON.mapType` can be used to define serialization and deserialization functions to prevent the need of repeating on each member. Example: + +```typescript +import {jsonObject, jsonMember, TypedJSON} from 'typedjson'; +import * as Decimal from 'decimal.js'; // Or any other library your type originates from + +TypedJSON.mapType(BigInt, { + deserializer: json => json == null ? json : BigInt(json), + serializer: value => value == null ? value : value.toString(), +}); + +TypedJSON.mapType(Decimal, { + deserializer: json => json == null ? json : new Decimal(json), + serializer: value => value == null ? value : value.toString(), +}); + +@jsonObject +class MappedTypes { + + @jsonMember + cryptoKey: bigint; + + @jsonMember + money: Decimal; +} + +const result = TypedJSON.parse({cryptoKey: '1234567890123456789', money: '12345.67'}, MappedTypes); +console.log(result.money instanceof Decimal); // true +console.log(typeof result.cryptoKey === 'bigint'); // true +``` + +Do note that in order to prevent the values from being parsed as `Number`, losing precision in the process, they have to be strings. + ### Collections Properties which are of type Array, Set, or Map require the special `@jsonArrayMember`, `@jsonSetMember` and `@jsonMapMember` property decorators (respectively), which require a type argument for members (and keys in case of Maps). For primitive types, the type arguments are the corresponding wrapper types, which the following example showcases. Everything else works the same way: @@ -121,6 +166,19 @@ class MyDataClass } ``` +### Any type +In case you don't want TypedJSON to make any conversion the `AnyT` type can be used. + +```typescript +import {AnyT, jsonObject, jsonMember} from 'typedjson'; + +@jsonObject +class Something { + @jsonMember(AnyT) + anythingGoes: any; +} +``` + ### Using without ReflectDecorators Without ReflectDecorators, `@jsonMember` requires an additional type argument, because TypeScript cannot infer it automatically: @@ -133,11 +191,11 @@ Without ReflectDecorators, `@jsonMember` requires an additional type argument, b class MyDataClass { - @jsonMember -+ @jsonMember({ constructor: Number }) ++ @jsonMember(Number) public prop1: number; - @jsonMember -+ @jsonMember({ constructor: MySecondDataClass }) ++ @jsonMember(MySecondDataClass) public prop2: MySecondDataClass; } ``` @@ -165,7 +223,7 @@ You can set it globally or on TypedJSON instance to have everything preserve nul On `@jsonObject` you can specify name of methods to be called before serializing the object or after it was deserialized. This method can be a static method or instance member. In case you have static and member with the same name - the member method is preferred. -#### serilizer and deseralizer +#### serializer and deserializer On `@jsonMember` decorator family you can provide your own functions to perform custom serialization and deserialization. This could be useful if you want to transform your input/output. For example, if instead of using javascript Date object you want to use moment.js object, you could use code like this: @@ -179,6 +237,28 @@ class UsingMoment { Note, that with those custom function you get full control over the serialization and deserialization process. This means, you will also receive any undefined (even if a property is not present), and null values. Basically, anything that comes in with an input json. +Custom deserializing and serializing functions can also fall back to the current runtime, so you don't need to create and configure a new one: + +```typescript +function objArrayDeserializer( + json: Array<{prop: string; shouldDeserialize: boolean}>, + params: CustomDeserializerParams, +) { + return json.filter(value => value.shouldDeserialize).map( + value => params.fallback(value, Inner), + ); +} + +@jsonObject +class Obj { + @jsonArrayMember(Inner, {deserializer: objArrayDeserializer}) + inners: Array; + + @jsonMember + str: string; +} +``` + #### Different property name in JSON and class You can provide a name for a property if it differs between a serialized JSON and your class definition. @@ -221,6 +301,56 @@ class Model { ## Limitations +### Declaration order & circular class dependencies + +Because of how decorators work at runtime, dependent class declaration order matters in TypedJSON. If a dependency is referenced before it is declared, it will result in an undefined reference and cause errors: + +```typescript +@jsonObject +class Foo { + @jsonMember // error, because Bar is only defined later + bar: Bar; + + @jsonMember(Bar) // error, because Bar is only defined later + baz: Bar; +} + + +@jsonObject +class Bar { + @jsonMember + foo: Foo; +} +``` + +This can be resolved by fixing the declaration order of your dependent classes (i.e. by moving `Bar` before `Foo` in the above example). + +In cases where this is not possible (most commonly because of a circular class-dependency), the more flexible lazy type definition syntax can be used instead: + +```diff + import {jsonObject, jsonMember} from 'typedjson'; + + @jsonObject + class Foo { +- @jsonMember ++ @jsonMember(() => Bar) + bar: Bar; + +- @jsonMember(Bar) ++ @jsonMember(() => Bar) + baz: Bar; + } + + @jsonObject + class Bar { +- @jsonMember ++ @jsonMember(() => Foo) + foo: Foo; + } +``` + +_Note: this is necessary even when inferring the type from the TypeScript type-annotation, requiring the use of an explicit lazy type definition at all times._ + ### Type-definitions TypedJSON is primarily for use-cases where object-trees are defined using instantiatible classes, and thus only supports a subset of all type-definitions possible in TypeScript. Interfaces and inline type definitions, for example, are not supported, and the following is not going to work so well: @@ -241,7 +371,7 @@ Instead, prefer creating the necessary class-structure for your object tree. ### Multi-dimensional arrays -TypedJSON only supports multi-dimensional arrays of a single type (can be polymorphic), and requires specifying the array dimension: +TypedJSON only supports multi-dimensional arrays of a single type (can be polymorphic), and requires specifying the array dimension to do so: ```typescript import 'reflect-metadata'; @@ -258,29 +388,6 @@ class MyDataClass } ``` -### Class declaration order matters - -When referencing a class in a nested object structure, the referenced class must be declared in advance, e.g.: - -```typescript -import 'reflect-metadata'; -import { jsonObject, jsonMember, jsonArrayMember, TypedJSON } from 'typedjson'; - -@jsonObject -class Employee -{ - @jsonMember - public name: string; -} - -@jsonObject -class Company -{ - @jsonArrayMember(Employee) - public employees: Employee[]; -} -``` - ### No inferred property types If using ReflectDecorators to infer the constructor (type) of properties, it's always required to manually specify the property type: diff --git a/spec/any.spec.ts b/spec/any.spec.ts new file mode 100644 index 0000000..a118e43 --- /dev/null +++ b/spec/any.spec.ts @@ -0,0 +1,167 @@ +import {AnyT, jsonArrayMember, jsonMember, jsonObject, jsonSetMember, TypedJSON} from '../src'; + +describe('AnyT', () => { + describe('on a simple class property', () => { + @jsonObject + class SimplePropertyAny { + @jsonMember(AnyT) + any: any; + + @jsonMember(AnyT) + anyNullable?: any | null; + } + + it('should deserialize simple object correctly', () => { + const result = TypedJSON.parse({ + any: {foo: 'bar'}, + anyNullable: {foo: 'bar'}, + }, SimplePropertyAny); + expect(result.any).toHaveProperties(['foo']); + expect(result.anyNullable).toHaveProperties(['foo']); + }); + + it('should deserialize class instance correctly', () => { + const foo = {foo: 'bar'}; + const result = TypedJSON.parse({ + any: foo, + anyNullable: foo, + }, SimplePropertyAny); + expect(result.any).toEqual(foo); + expect(result.anyNullable).toEqual(foo); + }); + + it('should serialize with referential equality', () => { + const foo = {foo: 'bar'}; + const simplePropertyAny = new SimplePropertyAny(); + simplePropertyAny.any = foo; + simplePropertyAny.anyNullable = foo; + const result: any = TypedJSON.toPlainJson(simplePropertyAny, SimplePropertyAny); + expect(result.any).toEqual(foo); + expect(result.anyNullable).toEqual(foo); + }); + }); + + describe('on arrays', () => { + @jsonObject + class ArrayPropertyAny { + @jsonArrayMember(AnyT) + any: Array; + + @jsonArrayMember(AnyT) + anyNullable?: Array | null; + } + + it('should deserialize simple object correctly', () => { + const result = TypedJSON.parse({ + any: [{foo: 'bar'}], + anyNullable: [{foo: 'bar'}], + }, ArrayPropertyAny); + expect(result.any).toBeInstanceOf(Array); + expect(result.any[0].foo).toEqual('bar'); + expect(result.anyNullable).toBeInstanceOf(Array); + expect(result.anyNullable[0].foo).toEqual('bar'); + }); + + it('should deserialize class instance correctly', () => { + const foo = {foo: 'bar'}; + const result = TypedJSON.parse({ + any: [foo], + anyNullable: [foo], + }, ArrayPropertyAny); + expect(result.any).toBeInstanceOf(Array); + expect(result.any[0]).toEqual(foo); + expect(result.anyNullable).toBeInstanceOf(Array); + expect(result.anyNullable[0]).toEqual(foo); + }); + + it('should serialize with referential equality', () => { + const foo = {foo: 'bar'}; + const arrayPropertyAny = new ArrayPropertyAny(); + arrayPropertyAny.any = [foo]; + arrayPropertyAny.anyNullable = [foo]; + const result: any = TypedJSON.toPlainJson(arrayPropertyAny, ArrayPropertyAny); + expect(result.any[0]).toEqual(foo); + expect(result.anyNullable[0]).toEqual(foo); + }); + }); + + describe('on set', () => { + @jsonObject + class SetPropertyAny { + + @jsonSetMember(AnyT) + any: Set; + + @jsonSetMember(AnyT) + anyNullable?: Set | null; + } + + it('should deserialize simple object correctly', () => { + const foo = {foo: 'bar'}; + const result = TypedJSON.parse({ + any: [foo, foo], + anyNullable: [foo, foo], + }, SetPropertyAny); + expect(result.any).toBeInstanceOf(Set); + expect(result.any.size).toBe(1); + expect(result.any.values().next().value).toEqual(foo); + expect(result.anyNullable).toBeInstanceOf(Set); + expect(result.anyNullable.size).toBe(1); + expect(result.anyNullable.values().next().value).toEqual(foo); + }); + + it('should deserialize with referential equality', () => { + const foo = {foo: 'bar'}; + const result = TypedJSON.parse({ + any: [foo, foo], + anyNullable: [foo, foo], + }, SetPropertyAny); + expect(result.any).toBeInstanceOf(Set); + expect(result.any.values().next().value).toBe(foo); + expect(result.anyNullable).toBeInstanceOf(Set); + expect(result.anyNullable.values().next().value).toBe(foo); + }); + + it('should serialize with referential equality', () => { + const foo = {foo: 'bar'}; + const setPropertyAny = new SetPropertyAny(); + setPropertyAny.any = new Set([foo, foo]); + setPropertyAny.anyNullable = new Set([foo, foo]); + const result: any = TypedJSON.toPlainJson(setPropertyAny, SetPropertyAny); + expect(result.any.values().next().value).toEqual(foo); + expect(result.anyNullable.values().next().value).toEqual(foo); + }); + }); + + it('should handle complex structures', () => { + @jsonObject + class Event { + + @jsonMember(AnyT) + data?: {[k: string]: any} | null; + } + + @jsonObject + class A { + + @jsonArrayMember(Event) + events: Array + } + + const result = TypedJSON.parse({ + events: [ + { + data: { + files: [ + { + name: 'file1', + }, + ], + }, + }, + ], + }, A); + + expect(result.events[0].data.files[0].name).toEqual('file1'); + }); +}); diff --git a/spec/array.spec.ts b/spec/array.spec.ts index 55a1e37..94e7377 100644 --- a/spec/array.spec.ts +++ b/spec/array.spec.ts @@ -1,7 +1,7 @@ -import {jsonObject, jsonMember, jsonArrayMember, TypedJSON} from "../src/typedjson"; -import { Everything, IEverything } from "./utils/everything"; +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../src'; +import {Everything, IEverything} from './utils/everything'; -describe('array of objects', function () { +describe('array of objects', () => { @jsonObject class Simple { @jsonMember @@ -10,36 +10,34 @@ describe('array of objects', function () { @jsonMember numProp: number; - constructor(init: {strProp: string, numProp: number}) - constructor() - constructor(init?: {strProp: string, numProp: number}) { - if (init) { + constructor(init?: {strProp: string; numProp: number}) { + if (init !== undefined) { this.strProp = init.strProp; this.numProp = init.numProp; } } - public foo() { + foo() { return `${this.strProp}-${this.numProp}`; } } - it('deserializes empty array', function () { + it('deserializes empty array', () => { const result = TypedJSON.parseAsArray('[]', Simple); expect(result).toBeDefined(); expect(result.length).toBe(0); }); - it('serialized empty array', function () { + it('serialized empty array', () => { const result = TypedJSON.stringifyAsArray([], Simple); expect(result).toBe('[]'); }); - it('deserialized should be of proper type', function () { + it('deserialized should be of proper type', () => { const expectation = [ - { strProp: 'delta', numProp: 4 }, - { strProp: 'bravo', numProp: 2 }, - { strProp: 'gamma', numProp: 0 }, + {strProp: 'delta', numProp: 4}, + {strProp: 'bravo', numProp: 2}, + {strProp: 'gamma', numProp: 0}, ]; const result = TypedJSON.parseAsArray(JSON.stringify(expectation), Simple); @@ -47,15 +45,16 @@ describe('array of objects', function () { expect(result.length).toBe(3, 'Deserialized array is of wrong length'); result.forEach((obj, index) => { expect(obj instanceof Simple).toBeTruthy(`${index} was not of type Simple`); - expect(obj).toHaveProperties(expectation[index], '${index} was deserialized incorrectly'); + expect(obj) + .toHaveProperties(expectation[index], '${index} was deserialized incorrectly'); }); }); - it('serialized should contain all elements', function () { + it('serialized should contain all elements', () => { const expectation = [ - { strProp: 'delta', numProp: 4 }, - { strProp: 'bravo', numProp: 2 }, - { strProp: 'gamma', numProp: 0 }, + {strProp: 'delta', numProp: 4}, + {strProp: 'bravo', numProp: 2}, + {strProp: 'gamma', numProp: 0}, ]; const result = TypedJSON.stringifyAsArray(expectation.map(obj => new Simple(obj)), Simple); @@ -64,32 +63,30 @@ describe('array of objects', function () { }); }); -describe('multidimensional arrays', function () { +describe('multidimensional arrays', () => { interface IWithArrays { - one: IEverything[]; - two: IEverything[][]; - deep: IEverything[][][][][][]; - arrayWithArray?: IWithArrays[][]; + one: Array; + two: Array>; + deep: Array>>>>>; + arrayWithArray?: Array>; } @jsonObject class WithArrays implements IWithArrays { @jsonArrayMember(Everything) - one: Everything[]; + one: Array; @jsonArrayMember(Everything, {dimensions: 2}) - two: Everything[][]; + two: Array>; @jsonArrayMember(Everything, {dimensions: 6}) - deep: Everything[][][][][][]; + deep: Array>>>>>; @jsonArrayMember(WithArrays, {dimensions: 2}) - arrayWithArray?: WithArrays[][]; + arrayWithArray?: Array>; - constructor(init: IWithArrays) - constructor() constructor(init?: IWithArrays) { - if (init) { + if (init !== undefined) { Object.assign(this, init); } } @@ -117,14 +114,14 @@ describe('multidimensional arrays', function () { expected ? Everything.expected() : Everything.create(), ], two: [ - [ expected ? Everything.expected() : Everything.create() ], - [ expected ? Everything.expected() : Everything.create() ], + [expected ? Everything.expected() : Everything.create()], + [expected ? Everything.expected() : Everything.create()], [], [], ], deep: [[[[ [], - [[ expected ? Everything.expected() : Everything.create() ]], + [[expected ? Everything.expected() : Everything.create()]], ]]]], arrayWithArray: [ [], @@ -135,7 +132,7 @@ describe('multidimensional arrays', function () { return expected ? new WithArrays(result) : result; } - function createTestArray(expected: boolean): IWithArrays[][] { + function createTestArray(expected: boolean): Array> { return [ [], [ @@ -146,11 +143,12 @@ describe('multidimensional arrays', function () { [ createTestObject(expected), ], - ] + ]; } - it('deserializes', function () { - const result = TypedJSON.parseAsArray(JSON.stringify(createTestArray(false)), WithArrays, undefined, 2); + it('deserializes', () => { + const testArray = JSON.stringify(createTestArray(false)); + const result = TypedJSON.parseAsArray(testArray, WithArrays, undefined, 2); expect(result).toBeOfLength(4); expect(result[0]).toBeOfLength(0); @@ -162,43 +160,43 @@ describe('multidimensional arrays', function () { expect(result[3][0]).toEqual(createTestObject(true)); }); - it('serializes', function () { + it('serializes', () => { const result = TypedJSON.stringifyAsArray(createTestArray(true), WithArrays, 2); expect(result).toBe(JSON.stringify(createTestArray(false))); }); }); -describe('array of raw objects', function () { +describe('array of raw objects', () => { @jsonObject class Translations { @jsonArrayMember(Object) - localization: any[]; + localization: Array; } function localization() { return [ { - "language_tag": "en_us", - "/actions/main": "My Game Actions", - "/actions/driving": "Driving", + language_tag: 'en_us', + '/actions/main': 'My Game Actions', + '/actions/driving': 'Driving', }, { - "language_tag": "fr", - "/actions/main": "Mes actions de jeux", - "/actions/driving": "Conduire", - } + language_tag: 'fr', + '/actions/main': 'Mes actions de jeux', + '/actions/driving': 'Conduire', + }, ]; } - it('should deserialize as is', function () { - const translations = TypedJSON.parse({"localization" : localization()}, Translations); + it('should deserialize as is', () => { + const translations = TypedJSON.parse({localization: localization()}, Translations); expect(translations).toBeDefined(); expect(translations instanceof Translations).toBeTruthy(); expect(translations.localization).toEqual(localization()); }); - it('should serialize as is', function () { + it('should serialize as is', () => { const translations = new Translations(); translations.localization = localization(); const json = TypedJSON.toPlainJson(translations, Translations); diff --git a/spec/base.spec.ts b/spec/base.spec.ts index 490e7c3..dbe6b50 100644 --- a/spec/base.spec.ts +++ b/spec/base.spec.ts @@ -1,27 +1,33 @@ -import { jsonObject, jsonMember, TypedJSON, jsonArrayMember } from "../src/typedjson"; -import { Everything } from "./utils/everything"; +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../src'; +import {Everything} from './utils/everything'; -describe('basic serialization of', function () { - describe('builtins', function () { - it('should deserialize', function () { +describe('basic serialization of', () => { + describe('builtins', () => { + it('should deserialize', () => { expect(TypedJSON.parse('"str"', String)).toEqual('str'); expect(TypedJSON.parse('45834', Number)).toEqual(45834); expect(TypedJSON.parse('true', Boolean)).toEqual(true); expect(TypedJSON.parse('1543915254', Date)).toEqual(new Date(1543915254)); - expect(TypedJSON.parse('"1970-01-18T20:51:55.254Z"', Date)).toEqual(new Date(1543915254)); + expect(TypedJSON.parse('-1543915254', Date)).toEqual(new Date(-1543915254)); + expect(TypedJSON.parse('"1970-01-18T20:51:55.254Z"', Date)) + .toEqual(new Date(1543915254)); - const dataBuffer = Uint8Array.from([100,117,112,97]) as any; + const dataBuffer = Uint8Array.from([100, 117, 112, 97]) as any; expect(TypedJSON.parse('"畤慰"', ArrayBuffer)).toEqual(dataBuffer); expect(TypedJSON.parse('"畤慰"', DataView)).toEqual(dataBuffer); expect(TypedJSON.parse('[100,117,112,97]', Uint8Array)).toEqual(dataBuffer); }); - it('should serialize', function () { + it('should serialize', () => { expect(TypedJSON.stringify('str', String)).toEqual('"str"'); expect(TypedJSON.stringify(45834, Number)).toEqual('45834'); expect(TypedJSON.stringify(true, Boolean)).toEqual('true'); - expect(TypedJSON.stringify(new Date(1543915254), Date)).toEqual(`"${new Date(1543915254).toISOString()}"`); - expect(TypedJSON.stringify(new Date('2018-12-04T09:20:54'), Date)).toEqual(`"${new Date('2018-12-04T09:20:54').toISOString()}"`); + expect(TypedJSON.stringify(new Date(1543915254), Date)) + .toEqual(`"${new Date(1543915254).toISOString()}"`); + expect(TypedJSON.stringify(new Date(-1543915254), Date)) + .toEqual(`"${new Date(-1543915254).toISOString()}"`); + expect(TypedJSON.stringify(new Date('2018-12-04T09:20:54'), Date)) + .toEqual(`"${new Date('2018-12-04T09:20:54').toISOString()}"`); const buffer = new ArrayBuffer(4); const view = new DataView(buffer); @@ -31,11 +37,12 @@ describe('basic serialization of', function () { view.setInt8(3, 97); expect(TypedJSON.stringify(buffer, ArrayBuffer)).toEqual('"畤慰"'); expect(TypedJSON.stringify(view, DataView)).toEqual('"畤慰"'); - expect(TypedJSON.stringify(new Uint8Array(buffer), Uint8Array)).toEqual('[100,117,112,97]'); + expect(TypedJSON.stringify(new Uint8Array(buffer), Uint8Array)) + .toEqual('[100,117,112,97]'); }); }); - describe('single class', function () { + describe('single class', () => { @jsonObject class Person { @jsonMember @@ -44,12 +51,12 @@ describe('basic serialization of', function () { @jsonMember lastName: string; - public getFullName() { - return this.firstName + " " + this.lastName; + getFullName() { + return `${this.firstName} ${this.lastName}`; } } - describe('deserialized', function () { + describe('deserialized', () => { beforeAll(function () { this.person = TypedJSON.parse('{ "firstName": "John", "lastName": "Doe" }', Person); }); @@ -64,9 +71,9 @@ describe('basic serialization of', function () { }); }); - describe('serialized', function () { - it('should contain all data', function () { - const person = new Person; + describe('serialized', () => { + it('should contain all data', () => { + const person = new Person(); person.firstName = 'John'; person.lastName = 'Doe'; expect(TypedJSON.stringify(person, Person)) @@ -75,8 +82,8 @@ describe('basic serialization of', function () { }); }); - describe('all types', function () { - it('should deserialized', function () { + describe('all types', () => { + it('should deserialized', () => { const everything = Everything.create(); const deserialized = TypedJSON.parse(JSON.stringify(everything), Everything); @@ -84,7 +91,7 @@ describe('basic serialization of', function () { expect(deserialized).toEqual(Everything.expected()); }); - it('should serialize', function () { + it('should serialize', () => { const everything = Everything.create(); const serialized = TypedJSON.stringify(new Everything(everything), Everything); @@ -93,17 +100,16 @@ describe('basic serialization of', function () { }); }); - describe('nullable', function () { - + describe('nullable', () => { @jsonObject class WithNullable { // nullable should be optional when not using preserve null @jsonMember - nullable?: string|null; + nullable?: string | null; } - it('should serialize to nothing', function () { - const nullClass = new WithNullable; + it('should serialize to nothing', () => { + const nullClass = new WithNullable(); nullClass.nullable = null; const serialized = TypedJSON.stringify(nullClass, WithNullable); @@ -111,22 +117,21 @@ describe('basic serialization of', function () { expect(serialized).toBe('{}'); }); - it('should deserialize to nothing when null', function () { + it('should deserialize to nothing when null', () => { const deserialized = TypedJSON.parse('{"nullable":null}', WithNullable); - expect(deserialized).toEqual(new WithNullable); + expect(deserialized).toEqual(new WithNullable()); }); - it('should deserialize to nothing when nothing', function () { + it('should deserialize to nothing when nothing', () => { const deserialized = TypedJSON.parse('{}', WithNullable); - expect(deserialized).toEqual(new WithNullable); + expect(deserialized).toEqual(new WithNullable()); }); }); - describe('class with defaults', function () { - - describe('by assigment', function () { + describe('class with defaults', () => { + describe('by assigment', () => { @jsonObject class WithDefaults { @jsonMember @@ -139,21 +144,21 @@ describe('basic serialization of', function () { bool: boolean = true; @jsonArrayMember(String) - arr: string[] = []; + arr: Array = []; @jsonMember present: number = 10; } - it('should use defaults when missing', function () { + it('should use defaults when missing', () => { const deserialized = TypedJSON.parse('{"present":5}', WithDefaults); - const expected = new WithDefaults; + const expected = new WithDefaults(); expected.present = 5; expect(deserialized).toEqual(expected); }); }); - describe('by constructor', function () { + describe('by constructor', () => { @jsonObject class WithCtr { @jsonMember @@ -166,7 +171,7 @@ describe('basic serialization of', function () { bool: boolean; @jsonArrayMember(String) - arr: string[]; + arr: Array; @jsonMember present: number; @@ -180,69 +185,92 @@ describe('basic serialization of', function () { } } - it('should use defaults when missing', function () { + it('should use defaults when missing', () => { const deserialized = TypedJSON.parse('{"present":5}', WithCtr); - const expected = new WithCtr; + const expected = new WithCtr(); expected.present = 5; expect(deserialized).toEqual(expected); }); }); }); - describe('getters/setters', function () { - + describe('getters/setters', () => { @jsonObject class SomeClass { - private _prop: string = "value"; + private _prop: string = 'value'; @jsonMember get prop(): string { return this._prop; } + set prop(val: string) { this._prop = val; } - private _getterOnly: string = "getter"; + private _getterOnly: string = 'getter'; @jsonMember get getterOnly(): string { return this._getterOnly; } - private _setterOnly: string = "setter"; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + private _setterOnly: string = 'setter'; @jsonMember set setterOnly(val: string) { this._setterOnly = val; } } - it('should serialize', function () { - const serialized = TypedJSON.stringify(new SomeClass, SomeClass); + it('should serialize', () => { + const serialized = TypedJSON.stringify(new SomeClass(), SomeClass); expect(serialized).toBe('{"prop":"value","getterOnly":"getter"}'); }); - it('should deserialize', function () { + it('should deserialize', () => { const deserialized = TypedJSON.parse( '{"prop":"other value","setterOnly":"ok"}', SomeClass, ); - const expected = new SomeClass; - expected.prop = "other value"; - expected.setterOnly = "ok"; + const expected = new SomeClass(); + expected.prop = 'other value'; + expected.setterOnly = 'ok'; expect(deserialized).toEqual(expected); }); - it('should deserialize ignoring readonly properties', function () { + it('should deserialize ignoring readonly properties', () => { pending('this is not supported as of now'); const deserialized = TypedJSON.parse( '{"prop":"other value","getterOnly":"ignored","setterOnly":"ok"}', SomeClass, ); - const expected = new SomeClass; - expected.prop = "other value"; - expected.setterOnly = "ok"; + const expected = new SomeClass(); + expected.prop = 'other value'; + expected.setterOnly = 'ok'; expect(deserialized).toEqual(expected); }); }); + + describe('structural inheritance', () => { + class JustForOrganizationalPurpose { + + } + + @jsonObject + class Child extends JustForOrganizationalPurpose { + + } + + it('should work for unannotated base class', () => { + expect(TypedJSON.stringify(new Child(), Child)).toEqual('{}'); + expect(TypedJSON.parse('{}', Child)).toEqual(new Child()); + }); + + it('should throw when using passing base for serialization/deserialization', () => { + expect(() => TypedJSON.stringify(new Child(), JustForOrganizationalPurpose)).toThrow(); + expect(() => TypedJSON.parse('{}', JustForOrganizationalPurpose)).toThrow(); + }); + }); }); diff --git a/spec/beforeSerialization.spec.ts b/spec/before-serialization.spec.ts similarity index 72% rename from spec/beforeSerialization.spec.ts rename to spec/before-serialization.spec.ts index 2f4ba2f..6abec4e 100644 --- a/spec/beforeSerialization.spec.ts +++ b/spec/before-serialization.spec.ts @@ -1,10 +1,9 @@ -import { jsonObject, jsonMember, TypedJSON } from "../src/typedjson"; +import {jsonMember, jsonObject, TypedJSON} from '../src'; -describe('beforeSerialization', function () { - - it('should call the static method', function () { +describe('beforeSerialization', () => { + it('should call the static method', () => { @jsonObject({ - beforeSerialization: 'beforeSerial' + beforeSerialization: 'beforeSerial', }) class Person { @jsonMember @@ -13,14 +12,14 @@ describe('beforeSerialization', function () { @jsonMember isOld: boolean; - public static beforeSerial() { + static beforeSerial() { // to have been called } } spyOn(Person, 'beforeSerial'); - const youngPerson = TypedJSON.parse({ age: 10 }, Person); + const youngPerson = TypedJSON.parse({age: 10}, Person); expect(youngPerson instanceof Person).toBeTruthy(); expect(youngPerson.isOld).toBeUndefined(); TypedJSON.stringify(youngPerson, Person); @@ -28,9 +27,9 @@ describe('beforeSerialization', function () { expect(Person.beforeSerial).toHaveBeenCalled(); }); - it('should call the member method', function () { + it('should call the member method', () => { @jsonObject({ - beforeSerialization: 'beforeSerial' + beforeSerialization: 'beforeSerial', }) class Person { @jsonMember @@ -39,7 +38,7 @@ describe('beforeSerialization', function () { @jsonMember isOld: boolean; - public beforeSerial() { + beforeSerial() { if (this.age < 20) { this.isOld = false; } else { @@ -48,8 +47,8 @@ describe('beforeSerialization', function () { } } - const youngPerson = TypedJSON.parse({ age: 10 }, Person); - const oldPerson = TypedJSON.parse({ age: 50 }, Person); + const youngPerson = TypedJSON.parse({age: 10}, Person); + const oldPerson = TypedJSON.parse({age: 50}, Person); expect(youngPerson instanceof Person).toBeTruthy(); expect(oldPerson instanceof Person).toBeTruthy(); @@ -62,9 +61,9 @@ describe('beforeSerialization', function () { expect(oldPersonUntyped['isOld']).toBeTruthy(); }); - it('should prefer the member method when there are both', function () { + it('should prefer the member method when there are both', () => { @jsonObject({ - beforeSerialization: 'beforeSerial' + beforeSerialization: 'beforeSerial', }) class Person { @jsonMember @@ -77,18 +76,18 @@ describe('beforeSerialization', function () { spyOn(this, 'beforeSerial'); } - public beforeSerial() { - // should call + static beforeSerial() { + // should NOT call } - public static beforeSerial() { - // should NOT call + beforeSerial() { + // should call } } spyOn(Person, 'beforeSerial'); - const youngPerson = TypedJSON.parse({ age: 10 }, Person); + const youngPerson = TypedJSON.parse({age: 10}, Person); expect(youngPerson instanceof Person).toBeTruthy(); expect(youngPerson.isOld).toBeUndefined(); diff --git a/spec/custom-deserializer.spec.ts b/spec/custom-deserializer.spec.ts index e4acf97..5aa57db 100644 --- a/spec/custom-deserializer.spec.ts +++ b/spec/custom-deserializer.spec.ts @@ -1,17 +1,17 @@ -import { jsonObject, jsonMember, jsonArrayMember, TypedJSON } from "../src/typedjson"; - -describe('custom member deserializer', function () { +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../src'; +import {CustomDeserializerParams} from '../src/metadata'; +describe('custom member deserializer', () => { @jsonObject class Person { - @jsonMember({ deserializer: ((json: any) => json[0]) }) + @jsonMember({deserializer: (json: any) => json[0]}) firstName: string; @jsonMember lastName: string; - public getFullName() { - return this.firstName + " " + this.lastName; + getFullName() { + return `${this.firstName} ${this.lastName}`; } } @@ -34,22 +34,23 @@ describe('custom member deserializer', function () { }); it('should not affect serialization', function () { - expect(TypedJSON.stringify(this.person, Person)).toBe('{"firstName":"John","lastName":"Doe"}'); + expect(TypedJSON.stringify(this.person, Person)) + .toBe('{"firstName":"John","lastName":"Doe"}'); }); - }); -describe('custom array member deserializer', function () { - +describe('custom array member deserializer', () => { @jsonObject class Obj { - @jsonArrayMember(Number, { deserializer: ((json: any) => json.split(',').map((v) => parseInt(v, 10))) }) - nums: number[]; + @jsonArrayMember(Number, { + deserializer: (json: any) => json.split(',').map((v) => parseInt(v, 10)), + }) + nums: Array; @jsonMember str: string; - public sum() { + sum() { return this.nums.reduce((sum, cur) => sum + cur, 0); } } @@ -59,7 +60,7 @@ describe('custom array member deserializer', function () { }); it('should properly deserialize', function () { - expect(this.obj.nums).toEqual([1,2,3,4,5]); + expect(this.obj.nums).toEqual([1, 2, 3, 4, 5]); expect(this.obj.str).toBe('Some string'); }); @@ -75,11 +76,9 @@ describe('custom array member deserializer', function () { it('should not affect serialization', function () { expect(TypedJSON.stringify(this.obj, Obj)).toBe('{"nums":[1,2,3,4,5],"str":"Some string"}'); }); - }); -describe('custom delegating array member serializer', function () { - +describe('custom delegating array member serializer', () => { @jsonObject class Inner { @jsonMember @@ -90,39 +89,45 @@ describe('custom delegating array member serializer', function () { } } - function objArrayDeserializer(values: {prop: string, shouldDeserialize: boolean}[]|undefined) { - if (values) { - return TypedJSON.parseAsArray( - values.filter(value => value.shouldDeserialize), - Inner, - ); + function objArrayDeserializer( + values: Array<{prop: string; shouldDeserialize: boolean}> | undefined, + ) { + if (values === undefined) { + return; } + + return TypedJSON.parseAsArray( + values.filter(value => value.shouldDeserialize), + Inner, + ); } @jsonObject class Obj { - @jsonArrayMember(Inner, { deserializer: objArrayDeserializer }) - inners: Inner[]; + @jsonArrayMember(Inner, {deserializer: objArrayDeserializer}) + inners: Array; @jsonMember str: string; } beforeAll(function () { - this.obj = TypedJSON.parse(JSON.stringify({ + this.obj = TypedJSON.parse( + JSON.stringify({ inners: [ { prop: 'something', - shouldDeserialize: false + shouldDeserialize: false, }, { prop: 'gogo', - shouldDeserialize: true + shouldDeserialize: true, }, ], str: 'Text', }), - Obj); + Obj, + ); }); it('should properly serialize', function () { @@ -135,5 +140,64 @@ describe('custom delegating array member serializer', function () { expect(this.obj.inners[0]).toHaveProperties({prop: 'gogo'}); expect(this.obj.inners[0].woo()).toEqual('hoo'); }); +}); +describe('custom delegating array member serializer with fallback', () => { + @jsonObject + class Inner { + @jsonMember + prop: string; + + woo(): string { + return 'hoo'; + } + } + + function objArrayDeserializer( + json: Array<{prop: string; shouldDeserialize: boolean}>, + params: CustomDeserializerParams, + ) { + return json.filter(value => value.shouldDeserialize).map( + value => params.fallback(value, Inner), + ); + } + + @jsonObject + class Obj { + @jsonArrayMember(Inner, {deserializer: objArrayDeserializer}) + inners: Array; + + @jsonMember + str: string; + } + + beforeAll(function () { + this.obj = TypedJSON.parse( + JSON.stringify({ + inners: [ + { + prop: 'something', + shouldDeserialize: false, + }, + { + prop: 'gogo', + shouldDeserialize: true, + }, + ], + str: 'Text', + }), + Obj, + ); + }); + + it('should properly serialize', function () { + expect(this.obj).toBeDefined(); + expect(this.obj instanceof Obj).toBeTruthy(); + expect(this.obj.str).toEqual('Text'); + expect(this.obj.inners.length).toEqual(1); + expect(this.obj.inners[0] instanceof Inner).toBeTruthy(); + expect(this.obj.inners[0]).not.toHaveProperties(['shouldDeserialize']); + expect(this.obj.inners[0]).toHaveProperties({prop: 'gogo'}); + expect(this.obj.inners[0].woo()).toEqual('hoo'); + }); }); diff --git a/spec/custom-serializer.spec.ts b/spec/custom-serializer.spec.ts index a979341..e07279d 100644 --- a/spec/custom-serializer.spec.ts +++ b/spec/custom-serializer.spec.ts @@ -1,17 +1,17 @@ -import {jsonObject, jsonMember, jsonArrayMember, TypedJSON} from "../src/typedjson"; - -describe('custom member serializer', function () { +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../src'; +import {CustomSerializerParams} from '../src/metadata'; +describe('custom member serializer', () => { @jsonObject class Person { - @jsonMember({ serializer: ((value: string) => value.split(' ')) }) + @jsonMember({serializer: (value: string) => value.split(' ')}) firstName: string; @jsonMember lastName: string; - public getFullName() { - return this.firstName + " " + this.lastName; + getFullName() { + return `${this.firstName} ${this.lastName}`; } } @@ -25,36 +25,35 @@ describe('custom member serializer', function () { it('should properly serialize', function () { expect(this.json).toEqual( { - firstName:['Mulit', 'term', 'name'], + firstName: ['Mulit', 'term', 'name'], lastName: 'Surname', - }); + }, + ); }); - it('should not affect deserialization', function () { + it('should not affect deserialization', () => { expect(TypedJSON.parse('{"firstName":"name","lastName":"last"}', Person)) .toEqual(Object.assign(new Person(), {firstName: 'name', lastName: 'last'})); }); - }); -describe('custom array member serializer', function () { - +describe('custom array member serializer', () => { @jsonObject class Obj { - @jsonArrayMember(Number, { serializer: ((values: number[]) => values.join(',')) }) - nums: number[]; + @jsonArrayMember(Number, {serializer: (values: Array) => values.join(',')}) + nums: Array; @jsonMember str: string; - public sum() { + sum() { return this.nums.reduce((sum, cur) => sum + cur, 0); } } beforeAll(function () { this.obj = new Obj(); - this.obj.nums = [3,45,34]; + this.obj.nums = [3, 45, 34]; this.obj.str = 'Text'; this.json = JSON.parse(TypedJSON.stringify(this.obj, Obj)); }); @@ -64,18 +63,17 @@ describe('custom array member serializer', function () { { nums: '3,45,34', str: 'Text', - }); + }, + ); }); - it('should not affect deserialization', function () { + it('should not affect deserialization', () => { expect(TypedJSON.parse('{"nums":[4,5,6,7],"str":"string"}', Obj)) - .toEqual(Object.assign(new Obj(), {nums: [4,5,6,7], str: 'string'} as Obj)); + .toEqual(Object.assign(new Obj(), {nums: [4, 5, 6, 7], str: 'string'} as Obj)); }); - }); -describe('custom delegating array member serializer', function () { - +describe('custom delegating array member serializer', () => { @jsonObject class Inner { @jsonMember @@ -91,7 +89,7 @@ describe('custom delegating array member serializer', function () { } } - function objArraySerializer(values: Inner[]) { + function objArraySerializer(values: Array) { return TypedJSON.toPlainArray( values.filter(value => value.shouldSerialize), Inner, @@ -100,8 +98,8 @@ describe('custom delegating array member serializer', function () { @jsonObject class Obj { - @jsonArrayMember(Inner, { serializer: objArraySerializer }) - inners: Inner[]; + @jsonArrayMember(Inner, {serializer: objArraySerializer}) + inners: Array; @jsonMember str: string; @@ -126,7 +124,62 @@ describe('custom delegating array member serializer', function () { }, ], str: 'Text', - }); + }, + ); }); +}); + +describe('custom delegating array member serializer with fallback', () => { + @jsonObject + class Inner { + @jsonMember + prop: string; + shouldSerialize: boolean; + + constructor(); + constructor(prop: string, shouldSerialize: boolean); + constructor(prop?: string, shouldSerialize?: boolean) { + this.prop = prop; + this.shouldSerialize = shouldSerialize; + } + } + + function objArraySerializer(value: Array, params: CustomSerializerParams) { + return value.filter(inner => inner.shouldSerialize).map( + inner => params.fallback(inner, Inner), + ); + } + + @jsonObject + class Obj { + @jsonArrayMember(Inner, {serializer: objArraySerializer}) + inners: Array; + + @jsonMember + str: string; + } + + beforeAll(function () { + this.obj = new Obj(); + this.obj.inners = [ + new Inner('valval', false), + new Inner('something', true), + ]; + this.obj.str = 'Text'; + this.json = JSON.parse(TypedJSON.stringify(this.obj, Obj)); + }); + + it('should properly serialize', function () { + expect(this.json).toEqual( + { + inners: [ + { + prop: 'something', + }, + ], + str: 'Text', + }, + ); + }); }); diff --git a/spec/errors.spec.ts b/spec/errors.spec.ts new file mode 100644 index 0000000..d122c82 --- /dev/null +++ b/spec/errors.spec.ts @@ -0,0 +1,24 @@ +import {jsonMember, jsonObject, TypedJSON} from '../src'; + +describe('errors', () => { + class CustomType { + } + + it('should be thrown when types could not be determined', () => { + @jsonObject + class TestNonDeterminableTypes { + + @jsonMember + bar: CustomType; + } + + const typedJson = new TypedJSON(TestNonDeterminableTypes); + typedJson.config({ + errorHandler: e => { + throw e; + }, + }); + + expect(() => typedJson.parse({bar: 'bar'})).toThrow(); + }); +}); diff --git a/spec/helpers.spec.ts b/spec/helpers.spec.ts new file mode 100644 index 0000000..2eecce2 --- /dev/null +++ b/spec/helpers.spec.ts @@ -0,0 +1,61 @@ +import {shouldOmitParseString} from '../src/helpers'; + +describe('helpers', () => { + describe('shouldOmitParseString', () => { + it('should handle plain numbers', () => { + expect(shouldOmitParseString('50', Number)).toEqual(false); + }); + it('should handle numbers with decimal places', () => { + expect(shouldOmitParseString('50.120', Number)).toEqual(false); + }); + it('should handle negative numbers', () => { + expect(shouldOmitParseString('-50', Number)).toEqual(false); + }); + it('should handle negative numbers with decimal places', () => { + expect(shouldOmitParseString('-50.120', Number)).toEqual(false); + }); + it('should handle numbers with a plus', () => { + expect(shouldOmitParseString('-50', Number)).toEqual(false); + }); + it('should handle negative numbers with a plus and decimal places', () => { + expect(shouldOmitParseString('+50.120', Number)).toEqual(false); + }); + it('should handle exponential notation', () => { + expect(shouldOmitParseString('1e2', Number)).toEqual(false); + }); + it('should handle exponential notation with decimal places', () => { + expect(shouldOmitParseString('1.120e2', Number)).toEqual(false); + }); + it('should handle negative exponential notation', () => { + expect(shouldOmitParseString('-1e2', Number)).toEqual(false); + }); + it('should handle negative exponential notation with decimal places', () => { + expect(shouldOmitParseString('-1.120e2', Number)).toEqual(false); + }); + it('should handle positive exponential notation', () => { + expect(shouldOmitParseString('+1e2', Number)).toEqual(false); + }); + it('should handle positive exponential notation with decimal places', () => { + expect(shouldOmitParseString('+1.120e2', Number)).toEqual(false); + }); + + it('should handle plain numeric dates', () => { + expect(shouldOmitParseString('50', Date)).toEqual(false); + }); + it('should handle negative dates', () => { + expect(shouldOmitParseString('-50', Date)).toEqual(false); + }); + it('should handle dates with a plus', () => { + expect(shouldOmitParseString('-50', Date)).toEqual(false); + }); + it('should handle dates in exponential notation', () => { + expect(shouldOmitParseString('1e2', Date)).toEqual(false); + }); + it('should handle dates in negative exponential notation', () => { + expect(shouldOmitParseString('-1e2', Date)).toEqual(false); + }); + it('should handle dates in positive exponential notation', () => { + expect(shouldOmitParseString('+1e2', Date)).toEqual(false); + }); + }); +}); diff --git a/spec/helpers/matchers.ts b/spec/helpers/matchers.ts index 3effe3d..883078a 100644 --- a/spec/helpers/matchers.ts +++ b/spec/helpers/matchers.ts @@ -1,11 +1,17 @@ -beforeEach(function() { +beforeEach(() => { jasmine.addMatchers({ toHaveProperties(util, customEqualityMatchers): jasmine.CustomMatcher { - function equalOnPropNames(actual: T, expected: (keyof T)[]): boolean { + function equalOnPropNames( + actual: T, + expected: Array, + ): boolean { return expected.every(prop => prop in actual); } - function equalOnPropValues(actual: T, expected: Partial): boolean { + function equalOnPropValues( + actual: T, + expected: Partial, + ): boolean { return Object.keys(expected) .every( key => key in actual @@ -16,8 +22,8 @@ beforeEach(function() { return { compare( actual: T, - expected: Partial|(keyof T)[], - ...customMsgs: any[] + expected: Partial | Array, + ...customMsgs: Array ) { let pass: boolean; let name: string; @@ -32,10 +38,14 @@ beforeEach(function() { return { pass, message: util.buildFailureMessage( - name, pass, actual, expected, ...customMsgs, + name, + pass, + actual, + expected, + ...customMsgs, ), }; - } + }, }; }, toBeInstanceOf(util): jasmine.CustomMatcher { @@ -43,15 +53,19 @@ beforeEach(function() { compare( actual: T, expected: Function, - ...customMsgs: any[] + ...customMsgs: Array ) { const pass = actual instanceof expected; return { pass, message: util.buildFailureMessage( - 'To be instance of', pass, actual, expected, ...customMsgs, + 'To be instance of', + pass, + actual, + expected, + ...customMsgs, ), - } + }; }, }; }, @@ -60,53 +74,59 @@ beforeEach(function() { compare>( actual: T, expected: number, - ...customMsgs: any[] + ...customMsgs: Array ) { - const pass = actual && actual.length === expected; + const pass = actual?.length === expected; return { pass, message: util.buildFailureMessage( - 'To be of length', pass, actual, expected, ...customMsgs, + 'To be of length', + pass, + actual, + expected, + ...customMsgs, ), - } + }; }, }; }, }); - jasmine.addCustomEqualityTester(function (first: any, second: any): boolean|undefined { - const firstAsInt8Array: Int8Array|undefined = tryAsInt8Array(first); - const secondAsInt8Array: Int8Array|undefined = tryAsInt8Array(second); + jasmine.addCustomEqualityTester((first: any, second: any): boolean | undefined => { + const firstAsInt8Array: Int8Array | undefined = tryAsInt8Array(first); + const secondAsInt8Array: Int8Array | undefined = tryAsInt8Array(second); - if (!firstAsInt8Array || !secondAsInt8Array) - { + if (firstAsInt8Array === undefined || secondAsInt8Array === undefined) { return; } if (firstAsInt8Array.length !== secondAsInt8Array.length) { return false; } - return firstAsInt8Array.every((num, i) => num == secondAsInt8Array[i]); + return firstAsInt8Array.every((num, i) => num === secondAsInt8Array[i]); }); }); -function tryAsInt8Array(obj: any): Int8Array|undefined { - if (obj instanceof ArrayBuffer) - { +function tryAsInt8Array(obj: any): Int8Array | undefined { + if (obj instanceof ArrayBuffer) { return new Int8Array(obj); - } - else if (ArrayBuffer.isView(obj)) - { + } else if (ArrayBuffer.isView(obj)) { return new Int8Array(obj.buffer); } } - +// eslint-disable-next-line @typescript-eslint/no-namespace declare namespace jasmine { + /* eslint-disable @typescript-eslint/method-signature-style */ interface Matchers { - toHaveProperties(expectation: Partial|(keyof T)[], ...expectationFailOutput: any[]): boolean; - toBeInstanceOf(expectation: Function, ...expectationFailOutput: any[]): boolean; + toHaveProperties( + expectation: Partial | Array, + ...expectationFailOutput: Array, + ): boolean; + + toBeInstanceOf(expectation: Function, ...expectationFailOutput: Array): boolean; } + interface ArrayLikeMatchers extends Matchers> { - toBeOfLength(expectation: number, ...expectationFailOutput: any[]): boolean; + toBeOfLength: (expectation: number, ...expectationFailOutput: Array) => boolean; } } diff --git a/spec/initializer.spec.ts b/spec/initializer.spec.ts index 4d17d10..8af5825 100644 --- a/spec/initializer.spec.ts +++ b/spec/initializer.spec.ts @@ -1,8 +1,7 @@ -import { jsonObject, jsonMember, TypedJSON } from "../src/typedjson"; +import {jsonMember, jsonObject, TypedJSON} from '../src'; -describe('initializer', function () { - - it('should be called', function() { +describe('initializer', () => { + it('should be called', () => { const initializerSpy = jasmine.createSpy().and.callFake((src, raw) => { expect(src instanceof Person).toBeFalsy(); expect(src.getDescription).toBeUndefined(); @@ -24,7 +23,7 @@ describe('initializer', function () { @jsonMember city: string; - public getAddressLine() { + getAddressLine() { return `${this.street}, ${this.city}`; } } @@ -44,21 +43,21 @@ describe('initializer', function () { this.address = address; } - public getDescription() { + getDescription() { return `${this.name} is living at ${this.address.getAddressLine()}`; } } const person = TypedJSON.parse( {name: 'John', address: {street: '44th', city: 'New York'}}, - Person + Person, )!; expect(person instanceof Person).toBeTruthy(); expect(person.getDescription()).toEqual('John is living at 44th, New York'); expect(initializerSpy).toHaveBeenCalled(); }); - it('should fail if nothing is returned', function() { + it('should fail if nothing is returned', () => { const initializerSpy = jasmine.createSpy().and.callFake(() => null); @jsonObject({ @@ -68,7 +67,7 @@ describe('initializer', function () { @jsonMember name: string; - public getDescription() { + getDescription() { return `${this.name} is his name`; } } @@ -84,7 +83,7 @@ describe('initializer', function () { expect(errorHandlerSpy).toHaveBeenCalled(); }); - it('should fail if wrong type is returned', function() { + it('should fail if wrong type is returned', () => { const initializerSpy = jasmine.createSpy() .and.callFake((src) => new Person2(src.name)); @@ -95,7 +94,7 @@ describe('initializer', function () { @jsonMember name: string; - public getDescription() { + getDescription() { return `${this.name} is his name`; } } @@ -107,7 +106,7 @@ describe('initializer', function () { this.name = name; } - public getDescription() { + getDescription() { return `${this.name} is his name`; } } @@ -123,7 +122,7 @@ describe('initializer', function () { expect(errorHandlerSpy).toHaveBeenCalled(); }); - it('should accept subtypes', function() { + it('should accept subtypes', () => { const initializerSpy = jasmine.createSpy() .and.callFake((src) => new Person2(src.name, 123)); @@ -138,12 +137,12 @@ describe('initializer', function () { this.name = name; } - public getDescription() { + getDescription() { return `${this.name} is his name`; } } - class Person2 extends Person{ + class Person2 extends Person { age: number; constructor(name: string, age: number) { @@ -151,7 +150,7 @@ describe('initializer', function () { this.age = age; } - public getDescription() { + getDescription() { return `${super.getDescription()} and is ${this.age}y old`; } } diff --git a/spec/just-json.spec.ts b/spec/just-json.spec.ts index adda2ab..50f4f13 100644 --- a/spec/just-json.spec.ts +++ b/spec/just-json.spec.ts @@ -1,8 +1,8 @@ -import { jsonArrayMember, jsonMember, jsonObject, TypedJSON } from "../src/typedjson"; +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../src'; -describe('json (without automatic stringify)', function () { - describe('string', function () { - it('should deserialize', function () { +describe('json (without automatic stringify)', () => { + describe('string', () => { + it('should deserialize', () => { // stringified json version cuz "" expect(TypedJSON.parse('"str"', String)).toEqual('str'); // already parsed @@ -12,16 +12,18 @@ describe('json (without automatic stringify)', function () { try { expect(TypedJSON.parse('"sdfs"fdsf"', String)).toEqual(undefined); fail(); - } catch(e) {} + } catch (e) { + // Ignore error + } }); - it('should serialize', function () { + it('should serialize', () => { expect(TypedJSON.toPlainJson('str', String)).toEqual('str'); }); }); - describe('rest of primitives', function () { - it('should deserialize', function () { + describe('rest of primitives', () => { + it('should deserialize', () => { expect(TypedJSON.parse(45834, Number)).toEqual(45834); expect(TypedJSON.parse(true, Boolean)).toEqual(true); expect(TypedJSON.parse(1543915254, Date)).toEqual(new Date(1543915254)); @@ -33,7 +35,7 @@ describe('json (without automatic stringify)', function () { expect(TypedJSON.parse([100, 117, 112, 97], Uint8Array)).toEqual(dataBuffer); }); - it('should serialize', function () { + it('should serialize', () => { expect(TypedJSON.toPlainJson(45834, Number)).toEqual(45834); expect(TypedJSON.toPlainJson(true, Boolean)).toEqual(true); const dateMs = new Date(1543915254); @@ -49,12 +51,12 @@ describe('json (without automatic stringify)', function () { view.setInt8(3, 97); expect(TypedJSON.toPlainJson(buffer, ArrayBuffer)).toEqual('畤慰'); expect(TypedJSON.toPlainJson(view, DataView)).toEqual('畤慰'); - expect(TypedJSON.toPlainJson(new Uint8Array(buffer), Uint8Array)).toEqual([100, 117, 112, 97]); + expect(TypedJSON.toPlainJson(new Uint8Array(buffer), Uint8Array)) + .toEqual([100, 117, 112, 97]); }); }); - describe('object', function () { - + describe('object', () => { @jsonObject class SomeThing { @jsonMember @@ -62,33 +64,39 @@ describe('json (without automatic stringify)', function () { @jsonMember propNum: number; @jsonArrayMember(String) - propArr: String[]; + propArr: Array; + @jsonMember + propDate: Date; } const json = Object.freeze({ propStr: 'dsgs', propNum: 653, propArr: ['dslfks'], + propDate: new Date(1543915254), }); - it('should deserialize', function () { + it('should deserialize', () => { expect(TypedJSON.parse(json, SomeThing)).toEqual(Object.assign(new SomeThing(), json)); - expect(TypedJSON.parseAsArray([json], SomeThing)).toEqual([Object.assign(new SomeThing(), json)]); + expect(TypedJSON.parseAsArray([json], SomeThing)) + .toEqual([Object.assign(new SomeThing(), json)]); }); - it('should serialize', function () { - expect(TypedJSON.toPlainJson(Object.assign(new SomeThing(), json), SomeThing)).toEqual(json); - expect(TypedJSON.toPlainArray([Object.assign(new SomeThing(), json)], SomeThing)).toEqual([json]); + it('should serialize', () => { + expect(TypedJSON.toPlainJson(Object.assign(new SomeThing(), json), SomeThing)) + .toEqual(json); + expect(TypedJSON.toPlainArray([Object.assign(new SomeThing(), json)], SomeThing)) + .toEqual([json]); }); }); - describe('array', function () { - it('should deserialize', function () { + describe('array', () => { + it('should deserialize', () => { expect(TypedJSON.parseAsArray(['alas', 'dfsd'], String)).toEqual(['alas', 'dfsd']); }); - it('should serialize', function () { - expect(TypedJSON.toPlainArray(['alas', 'dfsd'], String)).toEqual(['alas', 'dfsd']); + it('should serialize', () => { + expect(TypedJSON.toPlainArray(['alas', 'dfsd'], String)).toEqual(['alas', 'dfsd']); }); }); }); diff --git a/spec/lazy-types/a.model.ts b/spec/lazy-types/a.model.ts new file mode 100644 index 0000000..73ff553 --- /dev/null +++ b/spec/lazy-types/a.model.ts @@ -0,0 +1,16 @@ +import {jsonMember, jsonObject} from '../../src'; +import {B} from './b.model'; + +@jsonObject +export class A { + + @jsonMember(() => B) + b: B; + + @jsonMember + name: string; + + test(): true { + return true; + } +} diff --git a/spec/lazy-types/array.spec.ts b/spec/lazy-types/array.spec.ts new file mode 100644 index 0000000..6c8bea5 --- /dev/null +++ b/spec/lazy-types/array.spec.ts @@ -0,0 +1,143 @@ +import {AnyT, jsonArrayMember, jsonObject, TypedJSON} from '../../src'; +import {Everything, IEverything} from '../utils/everything'; + +describe('lazy, multidimensional arrays', () => { + interface IWithArrays { + one: Array; + two: Array>; + deep: Array>>>>>; + arrayWithArray?: Array>; + } + + @jsonObject + class WithArrays implements IWithArrays { + @jsonArrayMember(() => Everything) + one: Array; + + @jsonArrayMember(() => Everything, {dimensions: 2}) + two: Array>; + + @jsonArrayMember(() => Everything, {dimensions: 6}) + deep: Array>>>>>; + + @jsonArrayMember(() => WithArrays, {dimensions: 2}) + arrayWithArray?: Array>; + + constructor(init?: IWithArrays) { + if (init !== undefined) { + Object.assign(this, init); + } + } + } + + function createTestObject(expected: true): WithArrays; + function createTestObject(expected: false): IWithArrays; + function createTestObject(expected: boolean): IWithArrays; + function createTestObject(expected: boolean): IWithArrays { + const nested = { + one: [ + expected ? Everything.expected() : Everything.create(), + expected ? Everything.expected() : Everything.create(), + ], + two: [ + [], + [], + ], + deep: [[[[]]]], + }; + + const result = { + one: [ + expected ? Everything.expected() : Everything.create(), + expected ? Everything.expected() : Everything.create(), + ], + two: [ + [expected ? Everything.expected() : Everything.create()], + [expected ? Everything.expected() : Everything.create()], + [], + [], + ], + deep: [[[[ + [], + [[expected ? Everything.expected() : Everything.create()]], + ]]]], + arrayWithArray: [ + [], + [expected ? new WithArrays(nested) : nested], + ], + }; + + return expected ? new WithArrays(result) : result; + } + + function createTestArray(expected: boolean): Array> { + return [ + [], + [ + createTestObject(expected), + createTestObject(expected), + ], + [], + [ + createTestObject(expected), + ], + ]; + } + + it('deserializes', () => { + const testArray = JSON.stringify(createTestArray(false)); + const result = TypedJSON.parseAsArray(testArray, WithArrays, undefined, 2); + + expect(result).toBeOfLength(4); + expect(result[0]).toBeOfLength(0); + expect(result[1]).toBeOfLength(2); + expect(result[1][0]).toEqual(createTestObject(true)); + expect(result[1][1]).toEqual(createTestObject(true)); + expect(result[2]).toBeOfLength(0); + expect(result[3]).toBeOfLength(1); + expect(result[3][0]).toEqual(createTestObject(true)); + }); + + it('serializes', () => { + const result = TypedJSON.stringifyAsArray(createTestArray(true), WithArrays, 2); + + expect(result).toBe(JSON.stringify(createTestArray(false))); + }); +}); + +describe('lazy, array of raw objects', () => { + @jsonObject + class Translations { + @jsonArrayMember(() => AnyT) + localization: Array; + } + + function localization() { + return [ + { + language_tag: 'en_us', + '/actions/main': 'My Game Actions', + '/actions/driving': 'Driving', + }, + { + language_tag: 'fr', + '/actions/main': 'Mes actions de jeux', + '/actions/driving': 'Conduire', + }, + ]; + } + + it('should deserialize as is', () => { + const translations = TypedJSON.parse({localization: localization()}, Translations); + expect(translations).toBeDefined(); + expect(translations instanceof Translations).toBeTruthy(); + expect(translations.localization).toEqual(localization()); + }); + + it('should serialize as is', () => { + const translations = new Translations(); + translations.localization = localization(); + const json = TypedJSON.toPlainJson(translations, Translations); + expect(json).toEqual({localization: localization()}); + }); +}); diff --git a/spec/lazy-types/b.model.ts b/spec/lazy-types/b.model.ts new file mode 100644 index 0000000..cc421e4 --- /dev/null +++ b/spec/lazy-types/b.model.ts @@ -0,0 +1,16 @@ +import {jsonMember, jsonObject} from '../../src'; +import {A} from './a.model'; + +@jsonObject +export class B { + + @jsonMember(() => A) + a: A; + + @jsonMember + name: string; + + test(): true { + return true; + } +} diff --git a/spec/lazy-types/base.spec.ts b/spec/lazy-types/base.spec.ts new file mode 100644 index 0000000..3cc4393 --- /dev/null +++ b/spec/lazy-types/base.spec.ts @@ -0,0 +1,67 @@ +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../../src'; + +describe('lazy, basic serialization of', () => { + describe('class with defaults', () => { + describe('by assigment', () => { + @jsonObject + class WithDefaults { + @jsonMember + num: number = 2; + + @jsonMember + str: string = 'Hello world'; + + @jsonMember + bool: boolean = true; + + @jsonArrayMember(() => String) + arr: Array = []; + + @jsonMember + present: number = 10; + } + + it('should use defaults when missing', () => { + const deserialized = TypedJSON.parse('{"present":5}', WithDefaults); + const expected = new WithDefaults(); + expected.present = 5; + expect(deserialized).toEqual(expected); + }); + }); + + describe('by constructor', () => { + @jsonObject + class WithCtr { + @jsonMember + num: number; + + @jsonMember + str: string; + + @jsonMember + bool: boolean; + + @jsonArrayMember(() => String) + arr: Array; + + @jsonMember + present: number; + + constructor() { + this.num = 2; + this.str = 'Hello world'; + this.bool = true; + this.arr = []; + this.present = 10; + } + } + + it('should use defaults when missing', () => { + const deserialized = TypedJSON.parse('{"present":5}', WithCtr); + const expected = new WithCtr(); + expected.present = 5; + expect(deserialized).toEqual(expected); + }); + }); + }); +}); diff --git a/spec/lazy-types/custom-deserializer.spec.ts b/spec/lazy-types/custom-deserializer.spec.ts new file mode 100644 index 0000000..e0f568d --- /dev/null +++ b/spec/lazy-types/custom-deserializer.spec.ts @@ -0,0 +1,165 @@ +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../../src'; +import {CustomDeserializerParams} from '../../src/metadata'; + +describe('lazy, custom array member deserializer', () => { + @jsonObject + class Obj { + @jsonArrayMember(() => Number, { + deserializer: (json: any) => json.split(',').map((v) => parseInt(v, 10)), + }) + nums: Array; + + @jsonMember + str: string; + + sum() { + return this.nums.reduce((sum, cur) => sum + cur, 0); + } + } + + beforeAll(function () { + this.obj = TypedJSON.parse('{ "nums": "1,2,3,4,5", "str": "Some string" }', Obj); + }); + + it('should properly deserialize', function () { + expect(this.obj.nums).toEqual([1, 2, 3, 4, 5]); + expect(this.obj.str).toBe('Some string'); + }); + + it('should obj object of proper type', function () { + expect(this.obj instanceof Obj).toBeTruthy(); + }); + + it('should return object with callable functions', function () { + expect(this.obj.sum).toBeDefined(); + expect(this.obj.sum()).toBe(15); + }); + + it('should not affect serialization', function () { + expect(TypedJSON.stringify(this.obj, Obj)).toBe('{"nums":[1,2,3,4,5],"str":"Some string"}'); + }); +}); + +describe('lazy, custom delegating array member serializer', () => { + @jsonObject + class Inner { + @jsonMember + prop: string; + + woo(): string { + return 'hoo'; + } + } + + function objArrayDeserializer( + values: Array<{prop: string; shouldDeserialize: boolean}> | undefined, + ) { + if (values === undefined) { + return; + } + + return TypedJSON.parseAsArray( + values.filter(value => value.shouldDeserialize), + Inner, + ); + } + + @jsonObject + class Obj { + @jsonArrayMember(() => Inner, {deserializer: objArrayDeserializer}) + inners: Array; + + @jsonMember + str: string; + } + + beforeAll(function () { + this.obj = TypedJSON.parse( + JSON.stringify({ + inners: [ + { + prop: 'something', + shouldDeserialize: false, + }, + { + prop: 'gogo', + shouldDeserialize: true, + }, + ], + str: 'Text', + }), + Obj, + ); + }); + + it('should properly serialize', function () { + expect(this.obj).toBeDefined(); + expect(this.obj instanceof Obj).toBeTruthy(); + expect(this.obj.str).toEqual('Text'); + expect(this.obj.inners.length).toEqual(1); + expect(this.obj.inners[0] instanceof Inner).toBeTruthy(); + expect(this.obj.inners[0]).not.toHaveProperties(['shouldDeserialize']); + expect(this.obj.inners[0]).toHaveProperties({prop: 'gogo'}); + expect(this.obj.inners[0].woo()).toEqual('hoo'); + }); +}); + +describe('lazy, custom delegating array member serializer with fallback', () => { + @jsonObject + class Inner { + @jsonMember + prop: string; + + woo(): string { + return 'hoo'; + } + } + + function objArrayDeserializer( + json: Array<{prop: string; shouldDeserialize: boolean}>, + params: CustomDeserializerParams, + ) { + return json.filter(value => value.shouldDeserialize).map( + value => params.fallback(value, Inner), + ); + } + + @jsonObject + class Obj { + @jsonArrayMember(() => Inner, {deserializer: objArrayDeserializer}) + inners: Array; + + @jsonMember + str: string; + } + + beforeAll(function () { + this.obj = TypedJSON.parse( + JSON.stringify({ + inners: [ + { + prop: 'something', + shouldDeserialize: false, + }, + { + prop: 'gogo', + shouldDeserialize: true, + }, + ], + str: 'Text', + }), + Obj, + ); + }); + + it('should properly serialize', function () { + expect(this.obj).toBeDefined(); + expect(this.obj instanceof Obj).toBeTruthy(); + expect(this.obj.str).toEqual('Text'); + expect(this.obj.inners.length).toEqual(1); + expect(this.obj.inners[0] instanceof Inner).toBeTruthy(); + expect(this.obj.inners[0]).not.toHaveProperties(['shouldDeserialize']); + expect(this.obj.inners[0]).toHaveProperties({prop: 'gogo'}); + expect(this.obj.inners[0].woo()).toEqual('hoo'); + }); +}); diff --git a/spec/lazy-types/custom-serializer.spec.ts b/spec/lazy-types/custom-serializer.spec.ts new file mode 100644 index 0000000..74b8648 --- /dev/null +++ b/spec/lazy-types/custom-serializer.spec.ts @@ -0,0 +1,149 @@ +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../../src'; +import {CustomSerializerParams} from '../../src/metadata'; + +describe('lazy, custom array member serializer', () => { + @jsonObject + class Obj { + @jsonArrayMember(() => Number, {serializer: (values: Array) => values.join(',')}) + nums: Array; + + @jsonMember + str: string; + + sum() { + return this.nums.reduce((sum, cur) => sum + cur, 0); + } + } + + beforeAll(function () { + this.obj = new Obj(); + this.obj.nums = [3, 45, 34]; + this.obj.str = 'Text'; + this.json = JSON.parse(TypedJSON.stringify(this.obj, Obj)); + }); + + it('should properly serialize', function () { + expect(this.json).toEqual( + { + nums: '3,45,34', + str: 'Text', + }, + ); + }); + + it('should not affect deserialization', () => { + expect(TypedJSON.parse('{"nums":[4,5,6,7],"str":"string"}', Obj)) + .toEqual(Object.assign(new Obj(), {nums: [4, 5, 6, 7], str: 'string'} as Obj)); + }); +}); + +describe('lazy, custom delegating array member serializer', () => { + @jsonObject + class Inner { + @jsonMember + prop: string; + + shouldSerialize: boolean; + + constructor(); + constructor(prop: string, shouldSerialize: boolean); + constructor(prop?: string, shouldSerialize?: boolean) { + this.prop = prop; + this.shouldSerialize = shouldSerialize; + } + } + + function objArraySerializer(values: Array) { + return TypedJSON.toPlainArray( + values.filter(value => value.shouldSerialize), + Inner, + ); + } + + @jsonObject + class Obj { + @jsonArrayMember(() => Inner, {serializer: objArraySerializer}) + inners: Array; + + @jsonMember + str: string; + } + + beforeAll(function () { + this.obj = new Obj(); + this.obj.inners = [ + new Inner('valval', false), + new Inner('something', true), + ]; + this.obj.str = 'Text'; + this.json = JSON.parse(TypedJSON.stringify(this.obj, Obj)); + }); + + it('should properly serialize', function () { + expect(this.json).toEqual( + { + inners: [ + { + prop: 'something', + }, + ], + str: 'Text', + }, + ); + }); +}); + +describe('lazy, custom delegating array member serializer with fallback', () => { + @jsonObject + class Inner { + @jsonMember + prop: string; + + shouldSerialize: boolean; + + constructor(); + constructor(prop: string, shouldSerialize: boolean); + constructor(prop?: string, shouldSerialize?: boolean) { + this.prop = prop; + this.shouldSerialize = shouldSerialize; + } + } + + function objArraySerializer(value: Array, params: CustomSerializerParams) { + return value.filter(inner => inner.shouldSerialize).map( + inner => params.fallback(inner, Inner), + ); + } + + @jsonObject + class Obj { + @jsonArrayMember(() => Inner, {serializer: objArraySerializer}) + inners: Array; + + @jsonMember + str: string; + } + + beforeAll(function () { + this.obj = new Obj(); + this.obj.inners = [ + new Inner('valval', false), + new Inner('something', true), + ]; + this.obj.str = 'Text'; + this.json = JSON.parse(TypedJSON.stringify(this.obj, Obj)); + }); + + it('should properly serialize', function () { + expect(this.json).toEqual( + { + inners: [ + { + prop: 'something', + }, + ], + str: 'Text', + }, + ); + }); +}); diff --git a/spec/lazy-types/lazy-types.spec.ts b/spec/lazy-types/lazy-types.spec.ts new file mode 100644 index 0000000..d99baf8 --- /dev/null +++ b/spec/lazy-types/lazy-types.spec.ts @@ -0,0 +1,198 @@ +import { + jsonArrayMember, + jsonMapMember, + jsonMember, + jsonObject, + jsonSetMember, + TypedJSON, +} from '../../src'; +import {A} from './a.model'; +import {B} from './b.model'; + +describe('lazy, Lazy types', () => { + describe('simple member', () => { + @jsonObject + class Root { + + @jsonMember(() => Lazy) + lazy: Lazy; + } + + @jsonObject + class Lazy { + + @jsonMember + name: string; + } + + const typedJson = new TypedJSON(Root); + + it('should deserialize', () => { + const result = typedJson.parse({ + lazy: { + name: 'hello', + }, + }); + + expect(result.lazy).toBeInstanceOf(Lazy); + expect(result.lazy.name).toBe('hello'); + }); + + it('should serialize', () => { + const root = new Root(); + root.lazy = new Lazy(); + root.lazy.name = 'hello'; + const result: any = typedJson.toPlainJson(root); + + expect(result.lazy.name).toBe('hello'); + }); + }); + + describe('array member', () => { + @jsonObject + class Root { + + @jsonArrayMember(() => Lazy) + lazy: Array; + } + + @jsonObject + class Lazy { + + @jsonMember + name: string; + } + + const typedJson = new TypedJSON(Root); + + it('should deserialize', () => { + const result = typedJson.parse({ + lazy: [{name: 'hello'}], + }); + + expect(result.lazy.length).toBe(1); + expect(result.lazy[0]).toBeInstanceOf(Lazy); + expect(result.lazy[0].name).toBe('hello'); + }); + + it('should serialize', () => { + const root = new Root(); + const lazy = new Lazy(); + lazy.name = 'hello'; + root.lazy = [lazy]; + const result: any = typedJson.toPlainJson(root); + + expect(result.lazy.length).toBe(1); + expect(result.lazy[0].name).toBe('hello'); + }); + }); + + describe('map member', () => { + @jsonObject + class Root { + + @jsonMapMember(() => String, () => LazyValue) + lazy: Map; + } + + @jsonObject + class LazyValue { + + @jsonMember + name: string; + } + + const typedJson = new TypedJSON(Root); + + it('should deserialize', () => { + const result = typedJson.parse({ + lazy: [{key: 'key', value: {name: 'hello'}}], + }); + + expect(result.lazy.size).toBe(1); + expect(result.lazy).toBeInstanceOf(Map); + expect(result.lazy.get('key')).toBeInstanceOf(LazyValue); + expect(result.lazy.get('key').name).toBe('hello'); + }); + + it('should serialize', () => { + const root = new Root(); + const lazy = new LazyValue(); + lazy.name = 'hello'; + root.lazy = new Map([['key', lazy]]); + const result: any = typedJson.toPlainJson(root); + + expect(result.lazy.length).toBe(1); + expect(result.lazy[0].key).toBe('key'); + expect(result.lazy[0].value.name).toBe('hello'); + }); + }); + + describe('set member', () => { + @jsonObject + class Root { + + @jsonSetMember(() => Lazy) + lazy: Set; + } + + @jsonObject + class Lazy { + + @jsonMember + name: string; + } + + const typedJson = new TypedJSON(Root); + + it('should deserialize', () => { + const result = typedJson.parse({ + lazy: [{name: 'hello'}], + }); + + expect(result.lazy.size).toBe(1); + expect(result.lazy).toBeInstanceOf(Set); + expect(result.lazy.values().next().value).toBeInstanceOf(Lazy); + expect(result.lazy.values().next().value.name).toBe('hello'); + }); + + it('should serialize', () => { + const root = new Root(); + const lazy = new Lazy(); + lazy.name = 'hello'; + root.lazy = new Set([lazy]); + const result: any = typedJson.toPlainJson(root); + + expect(result.lazy.length).toBe(1); + expect(result.lazy[0].name).toBe('hello'); + }); + }); + + it('should work on multi file imports', () => { + const result = TypedJSON.parse({ + b: { + a: { + b: { + name: 'b2', + }, + name: 'a2', + }, + name: 'b1', + }, + name: 'a1', + }, A); + + expect(result).toBeInstanceOf(A); + expect(result.name).toBe('a1'); + expect(result.test()).toBeTrue(); + expect(result.b).toBeInstanceOf(B); + expect(result.b.name).toBe('b1'); + expect(result.b.test()).toBeTrue(); + expect(result.b.a).toBeInstanceOf(A); + expect(result.b.a.name).toBe('a2'); + expect(result.b.a.test()).toBeTrue(); + expect(result.b.a.b).toBeInstanceOf(B); + expect(result.b.a.b.name).toBe('b2'); + expect(result.b.a.b.test()).toBeTrue(); + }); +}); diff --git a/spec/lazy-types/map.spec.ts b/spec/lazy-types/map.spec.ts new file mode 100644 index 0000000..2d7fade --- /dev/null +++ b/spec/lazy-types/map.spec.ts @@ -0,0 +1,148 @@ +import {ArrayT, jsonMapMember, jsonMember, jsonObject, TypedJSON} from '../../src'; +import {MapShape} from '../../src/type-descriptor'; + +describe('lazy, map dictionary shape', () => { + @jsonObject + class Simple { + @jsonMember + strProp: string; + + @jsonMember + numProp: number; + + constructor(init?: {strProp: string; numProp: number}) { + if (init !== undefined) { + this.strProp = init.strProp; + this.numProp = init.numProp; + } + } + + foo() { + return `${this.strProp}-${this.numProp}`; + } + } + + @jsonObject + class DictMap { + @jsonMapMember(() => String, () => Simple, {shape: MapShape.OBJECT}) + prop: Map; + + getSetSize() { + return this.prop.size; + } + } + + it('deserializes', () => { + const result = TypedJSON.parse( + JSON.stringify( + { + prop: { + one: {strProp: 'delta', numProp: 4}, + two: {strProp: 'gamma', numProp: 7}, + }, + }, + ), + DictMap, + ); + + expect(result).toBeInstanceOf(DictMap); + expect(result.prop).toBeDefined(); + expect(result.prop).toBeInstanceOf(Map); + expect(result.prop.size).toBe(2); + expect(result.getSetSize()).toBe(2); + expect(result.prop.get('one').strProp).toBe('delta'); + expect(result.prop.get('two').strProp).toBe('gamma'); + }); + + it('serializes', () => { + const object = new DictMap(); + object.prop = new Map([ + ['one', new Simple({strProp: 'delta', numProp: 4})], + ['two', new Simple({strProp: 'gamma', numProp: 7})], + ]); + const result = TypedJSON.stringify(object, DictMap); + + expect(result).toBe(JSON.stringify({ + prop: { + one: {strProp: 'delta', numProp: 4}, + two: {strProp: 'gamma', numProp: 7}, + }, + })); + }); +}); + +describe('lazy, map of array dictionary shape', () => { + @jsonObject + class Simple { + @jsonMember + strProp: string; + + @jsonMember + numProp: number; + + constructor(init?: {strProp: string; numProp: number}) { + if (init !== undefined) { + this.strProp = init.strProp; + this.numProp = init.numProp; + } + } + + foo() { + return `${this.strProp}-${this.numProp}`; + } + } + + @jsonObject + class DictArrayMap { + @jsonMapMember(() => String, () => ArrayT(Simple), {shape: MapShape.OBJECT}) + prop: Map>; + + getSetSize() { + return this.prop.size; + } + } + + it('deserializes', () => { + const result = TypedJSON.parse( + JSON.stringify( + { + prop: { + one: [{strProp: 'delta', numProp: 4}], + two: [{strProp: 'gamma', numProp: 7}, {strProp: 'alpha', numProp: 2}], + }, + }, + ), + DictArrayMap, + ); + + expect(result).toBeInstanceOf(DictArrayMap); + expect(result.prop).toBeDefined(); + expect(result.prop).toBeInstanceOf(Map); + expect(result.prop.size).toBe(2); + expect(result.getSetSize()).toBe(2); + expect(result.prop.get('one').length).toBe(1); + expect(result.prop.get('one')[0].foo()).toBe('delta-4'); + expect(result.prop.get('two').length).toBe(2); + expect(result.prop.get('two')[0].foo()).toBe('gamma-7'); + expect(result.prop.get('two')[1].foo()).toBe('alpha-2'); + }); + + it('serializes', () => { + const object = new DictArrayMap(); + object.prop = new Map>([ + ['one', [new Simple({strProp: 'delta', numProp: 4})]], + ['two', [ + new Simple({strProp: 'gamma', numProp: 7}), + new Simple({strProp: 'alpha', numProp: 2}), + ]], + ]); + const result = TypedJSON.stringify(object, DictArrayMap); + + expect(result).toBe(JSON.stringify({ + prop: { + one: [{strProp: 'delta', numProp: 4}], + two: [{strProp: 'gamma', numProp: 7}, {strProp: 'alpha', numProp: 2}], + }, + })); + }); +}); diff --git a/spec/lazy-types/mapped-types.spec.ts b/spec/lazy-types/mapped-types.spec.ts new file mode 100644 index 0000000..8e2c88d --- /dev/null +++ b/spec/lazy-types/mapped-types.spec.ts @@ -0,0 +1,236 @@ +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../../src'; + +TypedJSON.setGlobalConfig({ + errorHandler: e => { + throw e; + }, +}); + +const date2000 = '2000-01-01T00:00:00.000Z'; +const date3000 = '3000-01-01T00:00:00.000Z'; + +describe('lazy, mapped types', () => { + class CustomType { + value: any; + + constructor(value: any) { + this.value = value; + } + + hasSucceeded(): boolean { + return this.value != null; + } + } + + @jsonObject + class MappedTypesSpec { + + @jsonMember + one: CustomType; + + @jsonMember + two: CustomType; + } + + const testData = { + one: 1, + two: 2, + }; + + describe('instance', () => { + const typedJson = new TypedJSON(MappedTypesSpec); + typedJson.mapType(CustomType, { + deserializer: json => new CustomType(json), + serializer: value => value.value, + }); + + it('deserializes', () => { + const result = typedJson.parse(testData); + + expect(result.one).toBeInstanceOf(CustomType); + expect(result.one.hasSucceeded()).toBeTrue(); + expect(result.two).toBeInstanceOf(CustomType); + expect(result.two.hasSucceeded()).toBeTrue(); + }); + + it('serializes', () => { + const test = new MappedTypesSpec(); + test.one = new CustomType(1); + test.two = new CustomType(2); + const result = typedJson.toPlainJson(test); + + expect(result).toEqual(testData); + }); + }); + + describe('works with constructor,', () => { + @jsonObject + class MappedTypeWithConstructor { + + @jsonMember(() => CustomType) + nullable: any; + } + + const typedJson = new TypedJSON(MappedTypeWithConstructor); + const CustomTypeMap = { + deserializer: json => new CustomType(json), + serializer: value => value.value, + }; + typedJson.mapType(CustomType, CustomTypeMap); + + it('deserializes', () => { + spyOn(CustomTypeMap, 'deserializer').and.callThrough(); + const result = typedJson.parse({nullable: 5}); + expect(result.nullable?.hasSucceeded()).toBeTrue(); + expect(result.nullable?.value).toBe(5); + expect(CustomTypeMap.deserializer).toHaveBeenCalled(); + }); + + it('serializes', () => { + spyOn(CustomTypeMap, 'serializer').and.callThrough(); + const object = new MappedTypeWithConstructor(); + object.nullable = new CustomType(5); + const result = typedJson.toPlainJson(object); + expect(CustomTypeMap.serializer).toHaveBeenCalled(); + expect(result).toEqual({nullable: 5}); + }); + }); + + it('can be overwritten with deserializer/serializer prop', () => { + const jsonMemberOptions = { + deserializer: json => new CustomType(0), + serializer: value => 1, + }; + + const CustomTypeMap = { + deserializer: json => new CustomType(json), + serializer: value => value.value, + }; + + spyOn(CustomTypeMap, 'serializer').and.callThrough(); + spyOn(jsonMemberOptions, 'serializer').and.callThrough(); + spyOn(CustomTypeMap, 'deserializer').and.callThrough(); + spyOn(jsonMemberOptions, 'deserializer').and.callThrough(); + + @jsonObject + class OverriddenSerializer { + @jsonMember(jsonMemberOptions) + overwritten: CustomType; + + @jsonMember + simple: CustomType; + } + + const typedJson = new TypedJSON(OverriddenSerializer); + typedJson.mapType(CustomType, CustomTypeMap); + + const parsed = typedJson.parse({data: 5, simple: 5}); + expect(CustomTypeMap.deserializer).toHaveBeenCalledTimes(1); + expect(jsonMemberOptions.deserializer).toHaveBeenCalledTimes(1); + expect(parsed.overwritten.value).toBe(0); + expect(parsed.simple.value).toBe(5); + + const plain: any = typedJson.toPlainJson(parsed); + expect(CustomTypeMap.serializer).toHaveBeenCalledTimes(1); + expect(jsonMemberOptions.serializer).toHaveBeenCalledTimes(1); + expect(plain.overwritten).toBe(1); + expect(plain.simple).toBe(5); + }); + + it('should use default when only mapping deserializer', () => { + @jsonObject + class OnlyDeSerializer { + @jsonMember + date: Date; + } + + const typedJson = new TypedJSON(OnlyDeSerializer); + typedJson.mapType(Date, { + deserializer: value => new Date(new Date(value).setFullYear(3000)), + }); + + const parsed = typedJson.parse({date: date2000}); + + expect(parsed.date.toISOString()).toEqual(date3000); + expect((typedJson.toPlainJson(parsed) as any).date.toString()) + .toEqual(new Date(date3000).toString()); + }); + + it('should use default when only mapping serializer', () => { + @jsonObject + class OnlySerializer { + @jsonMember + date: Date; + } + + const typedJson = new TypedJSON(OnlySerializer); + typedJson.mapType(Date, { + serializer: value => new Date(value.setFullYear(3000)).toISOString(), + }); + + const test = new OnlySerializer(); + test.date = new Date(date2000); + const result = typedJson.toPlainJson(test); + + expect(result).toEqual({date: date3000}); + expect(typedJson.parse({date: date2000}).date.toISOString()).toEqual(date2000); + }); + + it('should handle mapping arrays', () => { + @jsonObject + class MappedTypeWithArray { + + @jsonArrayMember(() => String) + array: Array; + } + + const typedJson = new TypedJSON(MappedTypeWithArray); + const ArrayTypeMap = { + deserializer: json => ['deserialized'], + serializer: value => ['serialized'], + }; + + typedJson.mapType(Array, ArrayTypeMap); + + spyOn(ArrayTypeMap, 'serializer').and.callThrough(); + spyOn(ArrayTypeMap, 'deserializer').and.callThrough(); + const parsed = typedJson.parse({array: ['hello']}); + expect(ArrayTypeMap.deserializer).toHaveBeenCalled(); + expect(parsed.array).toEqual(['deserialized']); + + const plain: any = typedJson.toPlainJson(parsed); + expect(ArrayTypeMap.serializer).toHaveBeenCalled(); + expect(plain.array).toEqual(['serialized']); + }); + + it('works on arrays', () => { + @jsonObject + class MappedTypeWithArray { + + @jsonArrayMember(() => CustomType) + array: Array; + } + + const typedJson = new TypedJSON(MappedTypeWithArray); + const CustomTypeMap = { + deserializer: json => new CustomType(json), + serializer: value => value.value, + }; + typedJson.mapType(CustomType, CustomTypeMap); + + spyOn(CustomTypeMap, 'serializer').and.callThrough(); + spyOn(CustomTypeMap, 'deserializer').and.callThrough(); + const parsed = typedJson.parse({array: [1, 5]}); + expect(CustomTypeMap.deserializer).toHaveBeenCalled(); + expect(parsed.array.map(c => c.value)).toEqual([1, 5]); + + const plain: any = typedJson.toPlainJson(parsed); + expect(CustomTypeMap.serializer).toHaveBeenCalled(); + expect(plain.array).toEqual([1, 5]); + }); +}); + +TypedJSON.setGlobalConfig({ + errorHandler: () => undefined, +}); + diff --git a/spec/lazy-types/polymorphism-abstract-class.spec.ts b/spec/lazy-types/polymorphism-abstract-class.spec.ts new file mode 100644 index 0000000..f9de480 --- /dev/null +++ b/spec/lazy-types/polymorphism-abstract-class.spec.ts @@ -0,0 +1,118 @@ +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../../src'; +import {isEqual} from '../utils/object-compare'; + +describe('lazy, polymorphic abstract classes', () => { + abstract class Node { + @jsonMember + name: string; + } + + @jsonObject + class SmallNode extends Node { + @jsonMember + inputType: string; + + @jsonMember + outputType: string; + } + + @jsonObject + class BigNode extends Node { + @jsonArrayMember(() => String) + inputs: Array; + + @jsonArrayMember(() => String) + outputs: Array; + + constructor() { + super(); + this.inputs = []; + this.outputs = []; + } + } + + @jsonObject({ + knownTypes: [BigNode, SmallNode], + }) + class Graph { + @jsonArrayMember(() => Node) + nodes: Array; + + @jsonMember + root: Node; + + constructor() { + this.nodes = []; + } + } + + let portTypeIndex = 0; + + function randPortType() { + const types = [ + 'string', + 'integer', + 'float', + 'boolean', + 'void', + ]; + + return types[portTypeIndex++ % types.length]; + } + + function test(log: boolean) { + const graph = new Graph(); + + for (let i = 0; i < 20; i++) { + let node: Node; + + if (i % 2 === 0) { + const bigNode = new BigNode(); + + bigNode.inputs = [ + randPortType(), + randPortType(), + randPortType(), + ]; + bigNode.outputs = [ + randPortType(), + randPortType(), + ]; + + node = bigNode; + } else { + const smallNode = new SmallNode(); + + smallNode.inputType = randPortType(); + smallNode.outputType = randPortType(); + + node = smallNode; + } + + node.name = `node_${i}`; + + if (i === 0) { + graph.root = node; + } else { + graph.nodes.push(node); + } + } + + const json = TypedJSON.stringify(graph, Graph); + const clone = TypedJSON.parse(json, Graph); + + if (log) { + console.log('Test: polymorphism with abstract property types...'); + console.log(graph); + console.log(JSON.parse(json)); + console.log(clone); + console.log('Test finished.'); + } + + return isEqual(graph, clone); + } + + it('should work', () => { + expect(test(false)).toBeTruthy(); + }); +}); diff --git a/spec/lazy-types/polymorphism-custom-names.spec.ts b/spec/lazy-types/polymorphism-custom-names.spec.ts new file mode 100644 index 0000000..b981e97 --- /dev/null +++ b/spec/lazy-types/polymorphism-custom-names.spec.ts @@ -0,0 +1,136 @@ +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../../src'; +import {isEqual} from '../utils/object-compare'; + +describe('lazy, polymorphic custom names', () => { + @jsonObject + class Person { + @jsonMember({name: 'first-name'}) + firstName: string; + + @jsonMember({name: 'last-name'}) + lastName: string; + + constructor(firstName?: string, lastName?: string) { + if (firstName !== undefined && lastName !== undefined) { + this.firstName = firstName; + this.lastName = lastName; + } + } + } + + @jsonObject + class Employee extends Person { + @jsonMember + salary: number; + + @jsonMember + joined: Date; + + constructor(); + constructor(firstName: string, lastName: string); + constructor(firstName: string, lastName: string, salary: number, joined: Date); + constructor(firstName?: string, lastName?: string, salary?: number, joined?: Date) { + super(firstName, lastName); + + if (salary !== undefined && joined !== undefined) { + this.salary = salary; + this.joined = joined; + } + } + } + + @jsonObject({name: 'part-time-employee'}) + class PartTimeEmployee extends Employee { + @jsonMember({name: 'work-hours'}) + workHours: number; + } + + @jsonObject() + class Investor extends Person { + @jsonMember({name: 'invest-amount'}) + investAmount: number; + + constructor(); + constructor(firstName: string, lastName: string, investAmount?: number); + constructor(firstName?: string, lastName?: string, investAmount?: number) { + super(firstName, lastName); + + this.investAmount = investAmount ?? 0; + } + } + + @jsonObject({name: 'company', knownTypes: [PartTimeEmployee, Investor]}) + class Company { + @jsonMember + name: string; + + @jsonArrayMember(() => Employee, {name: 'company-employees'}) + employees: Array; + + @jsonMember + owner: Person; + + constructor() { + this.employees = []; + } + } + + function test(owner: Person) { + // Create a Company. + const company = new Company(); + company.name = 'Json Types'; + company.owner = owner; + + // Add employees. + for (let j = 0; j < 20; j++) { + if (j % 2 === 0) { + const newPartTimeEmployee = new PartTimeEmployee( + `firstname_${j}`, + `lastname_${j}`, + Math.floor(Math.random() * 80000), + new Date(Date.now() - Math.floor(Math.random() * 80000)), + ); + + newPartTimeEmployee.workHours = Math.floor(Math.random() * 40); + + company.employees.push(newPartTimeEmployee); + } else { + company.employees.push(new Employee( + `firstname_${j}`, + `lastname_${j}`, + Math.floor(Math.random() * 80000), + new Date(Date.now() - Math.floor(Math.random() * 80000)), + )); + } + } + + const json = TypedJSON.stringify(company, Company); + const reparsed = TypedJSON.parse(json, Company); + + const success = isEqual(company, reparsed); + + if (!success) { + console.log('Polymorphism test failed'); + console.log('company', company); + console.log('json', JSON.parse(json)); + console.log('reparsed', reparsed); + } + + return success; + } + + it('should work', () => { + expect(test(new Employee('John', 'White', 240000, new Date(1992, 5, 27)))).toBeTruthy(); + expect(test(new Investor('John', 'White', 1700000))).toBeTruthy(); + const partTimeEmployee = new PartTimeEmployee( + 'John', + 'White', + 160000, + new Date(1992, 5, 27), + ); + + partTimeEmployee.workHours = 38; + expect(test(partTimeEmployee)).toBeTruthy(); + expect(test(new Person('John', 'White'))).toBeTruthy(); + }); +}); diff --git a/spec/lazy-types/polymorphism-custom-type-hints.spec.ts b/spec/lazy-types/polymorphism-custom-type-hints.spec.ts new file mode 100644 index 0000000..4dee868 --- /dev/null +++ b/spec/lazy-types/polymorphism-custom-type-hints.spec.ts @@ -0,0 +1,316 @@ +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../../src'; +import {IndexedObject} from '../../src/types'; + +describe('lazy, polymorphism custom type hints', () => { + describe('should work for a base class', () => { + @jsonObject({ + typeHintEmitter: (targetObject, sourceObject) => { + targetObject.personType = `${sourceObject.constructor.name}Type`; + }, + typeResolver: sourceObject => TYPE_MAP[sourceObject.personType], + }) + abstract class Person { + @jsonMember + firstName: string; + + @jsonMember + lastName: string; + + constructor(firstName?: string, lastName?: string); + constructor(firstName: string, lastName: string); + constructor(firstName?: string, lastName?: string) { + if (firstName !== undefined && lastName !== undefined) { + this.firstName = firstName; + this.lastName = lastName; + } + } + } + + @jsonObject + class Employee extends Person { + @jsonMember + salary: number; + + constructor(); + constructor(firstName: string, lastName: string, salary?: number); + constructor(firstName?: string, lastName?: string, salary?: number) { + super(firstName, lastName); + + if (salary !== undefined) { + this.salary = salary; + } + } + } + + @jsonObject + class PartTimeEmployee extends Employee { + @jsonMember + workHours: number; + } + + @jsonObject + class Investor extends Person { + @jsonMember + investAmount: number; + + constructor(); + constructor(firstName: string, lastName: string, investAmount?: number); + constructor(firstName?: string, lastName?: string, investAmount?: number) { + super(firstName, lastName); + + this.investAmount = investAmount ?? 0; + } + } + + const TYPE_MAP: IndexedObject = { + EmployeeType: Employee, + PartTimeEmployeeType: PartTimeEmployee, + InvestorType: Investor, + }; + + @jsonObject + class Company { + @jsonMember + name: string; + + @jsonArrayMember(() => Employee) + employees: Array = []; + + @jsonMember + owner: Person; + } + + it('should emit custom hint', () => { + const company = new Company(); + company.name = 'Json Types'; + company.owner = new Investor('John', 'White', 1700000); + + const partTime = new PartTimeEmployee('Abe', 'White', 160000); + partTime.workHours = 20; + company.employees = [ + new Employee('Donn', 'Worker', 240000), + partTime, + new Employee('Smith', 'Elly', 35500), + ]; + + const json = TypedJSON.toPlainJson(company, Company); + expect(json).toEqual({ + name: 'Json Types', + owner: { + personType: 'InvestorType', + firstName: 'John', + lastName: 'White', + investAmount: 1700000, + }, + employees: [ + { + personType: 'EmployeeType', + firstName: 'Donn', + lastName: 'Worker', + salary: 240000, + }, + { + personType: 'PartTimeEmployeeType', + firstName: 'Abe', + lastName: 'White', + salary: 160000, + workHours: 20, + }, + { + personType: 'EmployeeType', + firstName: 'Smith', + lastName: 'Elly', + salary: 35500, + }, + ], + }); + }); + + it('should resolve custom hints', () => { + const json = { + name: 'Json Types', + owner: { + personType: 'InvestorType', + firstName: 'John', + lastName: 'White', + investAmount: 1700000, + }, + employees: [ + { + personType: 'EmployeeType', + firstName: 'Donn', + lastName: 'Worker', + salary: 240000, + }, + { + personType: 'PartTimeEmployeeType', + firstName: 'Abe', + lastName: 'White', + salary: 160000, + workHours: 20, + }, + { + personType: 'EmployeeType', + firstName: 'Smith', + lastName: 'Elly', + salary: 35500, + }, + ], + }; + + const deserialized = TypedJSON.parse(JSON.stringify(json), Company); + + const company = new Company(); + company.name = 'Json Types'; + company.owner = new Investor('John', 'White', 1700000); + + const partTime = new PartTimeEmployee('Abe', 'White', 160000); + partTime.workHours = 20; + company.employees = [ + new Employee('Donn', 'Worker', 240000), + partTime, + new Employee('Smith', 'Elly', 35500), + ]; + expect(deserialized).toEqual(company); + }); + }); + + describe('should override parents', () => { + abstract class StructuralBase { + @jsonMember + value: string; + } + + @jsonObject({ + typeHintEmitter: (targetObject, sourceObject) => { + targetObject.type = (sourceObject.constructor as any).type; + }, + typeResolver: sourceObject => { + return sourceObject.type === 'sub-one' ? ConcreteOne : AnotherConcreteOne; + }, + }) + abstract class SemanticBaseOne extends StructuralBase { + @jsonMember + prop1: number; + } + + @jsonObject + class ConcreteOne extends SemanticBaseOne { + static type = 'sub-one'; + @jsonMember + propSub: string; + } + + @jsonObject + class AnotherConcreteOne extends SemanticBaseOne { + static type = 'sub-two'; + @jsonMember + propSub: number; + } + + @jsonObject({ + typeHintEmitter: (targetObject, sourceObject) => { + targetObject.hint = sourceObject instanceof ConcreteTwo ? 'first' : 'another'; + }, + typeResolver: sourceObject => { + return sourceObject.hint === 'first' ? ConcreteTwo : AnotherConcreteTwo; + }, + }) + abstract class SemanticBaseTwo extends StructuralBase { + @jsonMember + prop2: number; + } + + @jsonObject + class ConcreteTwo extends SemanticBaseTwo { + @jsonMember + propSub: string; + } + + @jsonObject + class AnotherConcreteTwo extends SemanticBaseTwo { + @jsonMember + propSub: number; + } + + it('should work for SemanticBaseOne', () => { + const inputAndResult: Array<[() => SemanticBaseOne, () => IndexedObject]> = [ + [ + () => { + const expected = new ConcreteOne(); + expected.value = 'base'; + expected.prop1 = 10; + expected.propSub = 'something'; + return expected; + }, + () => ({ + type: 'sub-one', + value: 'base', + prop1: 10, + propSub: 'something', + }), + ], + [ + () => { + const expected = new AnotherConcreteOne(); + expected.value = 'base value'; + expected.prop1 = 245; + expected.propSub = 234; + return expected; + }, + () => ({ + type: 'sub-two', + value: 'base value', + prop1: 245, + propSub: 234, + }), + ], + ]; + + inputAndResult.forEach(([inputFn, serializedFn]) => { + expect(TypedJSON.toPlainJson(inputFn(), SemanticBaseOne)).toEqual(serializedFn()); + expect(TypedJSON.parse(serializedFn(), SemanticBaseOne)).toEqual(inputFn()); + }); + }); + + it('should work for SemanticBaseTwo', () => { + const inputAndResult: Array<[() => SemanticBaseTwo, () => IndexedObject]> = [ + [ + () => { + const expected = new ConcreteTwo(); + expected.value = 'base'; + expected.prop2 = 546; + expected.propSub = 'something'; + return expected; + }, + () => ({ + hint: 'first', + value: 'base', + prop2: 546, + propSub: 'something', + }), + ], + [ + () => { + const expected = new AnotherConcreteTwo(); + expected.value = 'base value'; + expected.prop2 = 74; + expected.propSub = 234; + return expected; + }, + () => ({ + hint: 'another', + value: 'base value', + prop2: 74, + propSub: 234, + }), + ], + ]; + + inputAndResult.forEach(([inputFn, serializedFn]) => { + expect(TypedJSON.toPlainJson(inputFn(), SemanticBaseTwo)).toEqual(serializedFn()); + expect(TypedJSON.parse(serializedFn(), SemanticBaseTwo)).toEqual(inputFn()); + }); + }); + }); +}); diff --git a/spec/lazy-types/polymorphism-interface.spec.ts b/spec/lazy-types/polymorphism-interface.spec.ts new file mode 100644 index 0000000..95e0d85 --- /dev/null +++ b/spec/lazy-types/polymorphism-interface.spec.ts @@ -0,0 +1,130 @@ +import {AnyT, jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../../src'; +import {isEqual} from '../utils/object-compare'; + +describe('lazy, polymorphic interfaces', () => { + interface Point { + x: number; + y: number; + } + + @jsonObject + class SmallNode implements Point { + @jsonMember + x: number; + + @jsonMember + y: number; + + @jsonMember + inputType: string; + + @jsonMember + outputType: string; + } + + @jsonObject + class BigNode implements Point { + @jsonMember + x: number; + + @jsonMember + y: number; + + @jsonArrayMember(() => String) + inputs: Array; + + @jsonArrayMember(() => String) + outputs: Array; + + constructor() { + this.inputs = []; + this.outputs = []; + } + } + + @jsonObject({ + knownTypes: [BigNode, SmallNode], + }) + class GraphGrid { + @jsonArrayMember(() => AnyT) + points: Array; + + @jsonMember + root: Point; + + constructor() { + this.points = []; + } + } + + let portTypeIndex = 0; + + function randPortType() { + const types = [ + 'string', + 'integer', + 'float', + 'boolean', + 'void', + ]; + + return types[portTypeIndex++ % types.length]; + } + + function test(log: boolean) { + const graph = new GraphGrid(); + + for (let i = 0; i < 20; i++) { + let point: Point; + + if (i % 2 === 0) { + const bigNode = new BigNode(); + + bigNode.inputs = [ + randPortType(), + randPortType(), + randPortType(), + ]; + bigNode.outputs = [ + randPortType(), + randPortType(), + ]; + + point = bigNode; + } else { + const smallNode = new SmallNode(); + + smallNode.inputType = randPortType(); + smallNode.outputType = randPortType(); + + point = smallNode; + } + + point.x = Math.random(); + point.y = Math.random(); + + if (i === 0) { + graph.root = point; + } else { + graph.points.push(point); + } + } + + const json = TypedJSON.stringify(graph, GraphGrid); + const clone = TypedJSON.parse(json, GraphGrid); + + if (log) { + console.log('Test: polymorphism with interface property types...'); + console.log(graph); + console.log(JSON.parse(json)); + console.log(clone); + console.log('Test finished.'); + } + + return isEqual(graph, clone); + } + + it('should work', () => { + expect(test(false)).toBeTruthy(); + }); +}); diff --git a/spec/lazy-types/polymorphism-nested-arrays.spec.ts b/spec/lazy-types/polymorphism-nested-arrays.spec.ts new file mode 100644 index 0000000..83ea183 --- /dev/null +++ b/spec/lazy-types/polymorphism-nested-arrays.spec.ts @@ -0,0 +1,135 @@ +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../../src'; +import {isEqual} from '../utils/object-compare'; + +describe('lazy, polymorphism in nested arrays', () => { + abstract class Node { + @jsonMember + name: string; + } + + @jsonObject + class SmallNode extends Node { + @jsonMember + inputType: string; + + @jsonMember + outputType: string; + } + + @jsonObject + class BigNode extends Node { + @jsonArrayMember(() => String) + inputs: Array; + + @jsonArrayMember(() => String) + outputs: Array; + + constructor() { + super(); + this.inputs = []; + this.outputs = []; + } + } + + @jsonObject({knownTypes: [BigNode, SmallNode]}) + class Graph { + @jsonArrayMember(() => Node, {dimensions: 2}) + items: Array>; + + @jsonArrayMember(() => SmallNode, {dimensions: 2}) + smallItems: Array>; + + constructor() { + this.items = []; + this.smallItems = []; + } + } + + let portTypeIndex = 0; + + function randPortType() { + const types = [ + 'string', + 'integer', + 'float', + 'boolean', + 'void', + ]; + + return types[portTypeIndex++ % types.length]; + } + + function test(log: boolean) { + const graph = new Graph(); + + for (let i = 0; i < 20; i++) { + graph.smallItems.push([]); + + for (let j = 0; j < 8; j++) { + const node = new SmallNode(); + + node.name = `smallnode_${i}_${j}`; + node.inputType = randPortType(); + node.outputType = randPortType(); + + graph.smallItems[i].push(node); + } + } + + for (let i = 0; i < 20; i++) { + graph.items.push([]); + + for (let j = 0; j < 8; j++) { + let node: Node; + + if (j % 2 === 0) { + const bigNode = new BigNode(); + + bigNode.inputs = [ + randPortType(), + randPortType(), + randPortType(), + ]; + bigNode.outputs = [ + randPortType(), + randPortType(), + ]; + + node = bigNode; + } else { + const smallNode = new SmallNode(); + + smallNode.inputType = randPortType(); + smallNode.outputType = randPortType(); + + node = smallNode; + } + + node.name = `node_${i}_${j}`; + + graph.items[i].push(node); + } + } + + const json = TypedJSON.stringify(graph, Graph); + + if (log) { + console.log('Test: polymorphism with nested arrays...'); + console.log(graph); + console.log(JSON.parse(json)); + } + + const clone = TypedJSON.parse(json, Graph); + + if (log) { + console.log(clone); + console.log('Test finished.'); + } + + return isEqual(graph, clone); + } + + it('should work', () => { + expect(test(false)).toBeTruthy(); + }); +}); diff --git a/spec/lazy-types/polymorphism.spec.ts b/spec/lazy-types/polymorphism.spec.ts new file mode 100644 index 0000000..46c62a9 --- /dev/null +++ b/spec/lazy-types/polymorphism.spec.ts @@ -0,0 +1,138 @@ +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../../src'; +import {isEqual} from '../utils/object-compare'; + +describe('lazy, polymorphism', () => { + @jsonObject + class Person { + @jsonMember + firstName: string; + + @jsonMember + lastName: string; + + constructor(); + constructor(firstName: string, lastName: string); + constructor(firstName?: string, lastName?: string) { + if (firstName !== undefined && lastName !== undefined) { + this.firstName = firstName; + this.lastName = lastName; + } + } + } + + @jsonObject + class Employee extends Person { + @jsonMember + salary: number; + + @jsonMember + joined: Date; + + constructor(); + constructor(firstName: string, lastName: string); + constructor(firstName: string, lastName: string, salary: number, joined: Date); + constructor(firstName?: string, lastName?: string, salary?: number, joined?: Date) { + super(firstName, lastName); + + if (salary !== undefined && joined !== undefined) { + this.salary = salary; + this.joined = joined; + } + } + } + + @jsonObject + class PartTimeEmployee extends Employee { + @jsonMember + workHours: number; + } + + @jsonObject + class Investor extends Person { + @jsonMember + investAmount: number; + + constructor(); + constructor(firstName: string, lastName: string, investAmount?: number); + constructor(firstName?: string, lastName?: string, investAmount?: number) { + super(firstName, lastName); + + this.investAmount = investAmount ?? 0; + } + } + + @jsonObject({knownTypes: [PartTimeEmployee, Investor]}) + class Company { + @jsonMember + name: string; + + @jsonArrayMember(() => Employee) + employees: Array; + + @jsonMember + owner: Person; + + constructor() { + this.employees = []; + } + } + + function test(owner: Person) { + // Create a Company. + const company = new Company(); + company.name = 'Json Types'; + company.owner = owner; + + // Add employees. + for (let j = 0; j < 20; j++) { + if (j % 2 === 0) { + const newPartTimeEmployee = new PartTimeEmployee( + `firstname_${j}`, + `lastname_${j}`, + Math.floor(Math.random() * 80000), + new Date(Date.now() - Math.floor(Math.random() * 80000)), + ); + + newPartTimeEmployee.workHours = Math.floor(Math.random() * 40); + + company.employees.push(newPartTimeEmployee); + } else { + company.employees.push(new Employee( + `firstname_${j}`, + `lastname_${j}`, + Math.floor(Math.random() * 80000), + new Date(Date.now() - Math.floor(Math.random() * 80000)), + )); + } + } + + const json = TypedJSON.stringify(company, Company); + const reparsed = TypedJSON.parse(json, Company); + + const success = isEqual(company, reparsed); + + if (!success) { + console.log('Polymorphism test failed'); + console.log('company', company); + console.log('json', JSON.parse(json)); + console.log('reparsed', reparsed); + } + + return success; + } + + it('should work', () => { + expect(test(new Employee('John', 'White', 240000, new Date(1992, 5, 27)))).toBeTruthy(); + expect(test(new Investor('John', 'White', 1700000))).toBeTruthy(); + const partTimeEmployee = new PartTimeEmployee( + 'John', + 'White', + 160000, + new Date(1992, 5, 27), + ); + + partTimeEmployee.workHours = 38; + expect(test(partTimeEmployee)).toBeTruthy(); + expect(test(new Person('John', 'White'))).toBeTruthy(); + }); +}); diff --git a/spec/lazy-types/preserve-null.spec.ts b/spec/lazy-types/preserve-null.spec.ts new file mode 100644 index 0000000..7ada0e6 --- /dev/null +++ b/spec/lazy-types/preserve-null.spec.ts @@ -0,0 +1,49 @@ +import {jsonArrayMember, jsonMapMember, jsonObject, TypedJSON} from '../../src'; + +describe('lazy, preserveNull', () => { + it('should preserve nulls in array', () => { + @jsonObject + class Person { + @jsonArrayMember(() => String, {preserveNull: true}) + names: Array; + } + + const input = new Person(); + input.names = [null, 'one', null, null, 'two', null]; + const json = TypedJSON.stringify(input, Person); + expect(json).toEqual('{"names":[null,"one",null,null,"two",null]}'); + const obj = TypedJSON.parse({names: [null, 'one', null, null, 'two', null]}, Person); + expect(obj).toEqual(input); + }); + + it('should preserve nulls in maps', () => { + @jsonObject + class Person { + @jsonMapMember(() => String, () => String, {preserveNull: true}) + map: Map; + } + + const input = new Person(); + input.map = new Map([ + ['one', null], + ['two', null], + ['three', 'val'], + ]); + const json = TypedJSON.stringify(input, Person); + expect(json).toEqual( + '{"map":[{"key":"one","value":null},{"key":"two","value":null},' + + '{"key":"three","value":"val"}]}', + ); + const obj = TypedJSON.parse( + { + map: [ + {key: 'one', value: null}, + {key: 'two', value: null}, + {key: 'three', value: 'val'}, + ], + }, + Person, + ); + expect(obj).toEqual(input); + }); +}); diff --git a/spec/lazy-types/set.spec.ts b/spec/lazy-types/set.spec.ts new file mode 100644 index 0000000..913c376 --- /dev/null +++ b/spec/lazy-types/set.spec.ts @@ -0,0 +1,233 @@ +import {AnyT, ArrayT, jsonMember, jsonObject, jsonSetMember, SetT, TypedJSON} from '../../src'; +import {Everything} from '../utils/everything'; + +describe('lazy, set of objects', () => { + @jsonObject + class Simple { + @jsonMember + strProp: string; + + @jsonMember + numProp: number; + + constructor(init?: {strProp: string; numProp: number}) { + if (init !== undefined) { + this.strProp = init.strProp; + this.numProp = init.numProp; + } + } + + foo() { + return `${this.strProp}-${this.numProp}`; + } + } + + it('deserializes empty set', () => { + const result = TypedJSON.parseAsSet('[]', Simple); + expect(result).toBeDefined(); + expect(result.size).toBe(0); + }); + + it('serialized empty set', () => { + const result = TypedJSON.stringifyAsSet(new Set(), Simple); + expect(result).toBe('[]'); + }); + + it('deserialized should be of proper type', () => { + const expectation = [ + {strProp: 'delta', numProp: 4}, + {strProp: 'bravo', numProp: 2}, + {strProp: 'gamma', numProp: 0}, + ]; + + const result = TypedJSON.parseAsSet(JSON.stringify(expectation), Simple); + + expect(result.size).toBe(3, 'Deserialized set is of wrong size'); + result.forEach((obj) => { + expect(obj).toBeInstanceOf(Simple); + expect(obj) + .toHaveProperties(expectation.find((expected) => expected.strProp === obj.strProp)); + }); + }); + + it('serialized should contain all elements', () => { + const expectation = [ + {strProp: 'delta', numProp: 4}, + {strProp: 'bravo', numProp: 2}, + {strProp: 'gamma', numProp: 0}, + ]; + + const set = new Set(expectation.map(obj => new Simple(obj))); + const result = TypedJSON.stringifyAsSet(set, Simple); + + expect(result).toBe(JSON.stringify(expectation)); + }); +}); + +describe('lazy, set member', () => { + @jsonObject + class WithSet { + @jsonSetMember(() => Everything) + prop: Set; + + getSetSize() { + return this.prop.size; + } + } + + it('deserializes', () => { + const object = {prop: [Everything.create(), Everything.create()]}; + const result = TypedJSON.parse(JSON.stringify(object), WithSet); + + expect(result).toBeInstanceOf(WithSet); + expect(result.prop).toBeDefined(); + expect(result.prop).toBeInstanceOf(Set); + expect(result.prop.size).toBe(2); + expect(result.getSetSize()).toBe(2); + expect(Array.from(result.prop)).toEqual([Everything.expected(), Everything.expected()]); + }); + + it('serializes', () => { + const object = new WithSet(); + object.prop = new Set([Everything.expected(), Everything.expected()]); + const result = TypedJSON.stringify(object, WithSet); + + expect(result).toBe(JSON.stringify({prop: [Everything.create(), Everything.create()]})); + }); +}); + +describe('lazy, set array member', () => { + @jsonObject + class Simple { + @jsonMember + strProp: string; + + @jsonMember + numProp: number; + + constructor(init?: {strProp: string; numProp: number}) { + if (init !== undefined) { + this.strProp = init.strProp; + this.numProp = init.numProp; + } + } + + foo() { + return `${this.strProp}-${this.numProp}`; + } + } + + @jsonObject + class WithSet { + @jsonMember(() => SetT(ArrayT(Simple))) + prop: Set>; + + getSetSize() { + return this.prop.size; + } + } + + it('deserializes', () => { + const result = TypedJSON.parse( + JSON.stringify( + { + prop: [ + [ + {strProp: 'delta', numProp: 4}, + {strProp: 'bravo', numProp: 2}, + {strProp: 'gamma', numProp: 0}, + ], + [ + {strProp: 'alpha', numProp: 3245}, + {strProp: 'zeta', numProp: 4358}, + ], + ], + }, + ), + WithSet, + ); + + expect(result).toBeInstanceOf(WithSet); + expect(result.prop).toBeDefined(); + expect(result.prop).toBeInstanceOf(Set); + expect(result.prop.size).toBe(2); + expect(result.getSetSize()).toBe(2); + expect(Array.from(result.prop)).toEqual([ + [ + new Simple({strProp: 'delta', numProp: 4}), + new Simple({strProp: 'bravo', numProp: 2}), + new Simple({strProp: 'gamma', numProp: 0}), + ], + [ + new Simple({strProp: 'alpha', numProp: 3245}), + new Simple({strProp: 'zeta', numProp: 4358}), + ], + ]); + }); + + it('serializes', () => { + const object = new WithSet(); + object.prop = new Set>([ + [new Simple({strProp: 'delta', numProp: 4})], + [ + new Simple({strProp: 'alpha', numProp: 3245}), + new Simple({strProp: 'zeta', numProp: 4358}), + ], + ]); + const result = TypedJSON.stringify(object, WithSet); + + expect(result).toBe(JSON.stringify({ + prop: [ + [ + { + strProp: 'delta', + numProp: 4, + }, + ], + [ + { + strProp: 'alpha', + numProp: 3245, + }, + { + strProp: 'zeta', + numProp: 4358, + }, + ], + ], + })); + }); +}); + +describe('lazy, set of raw objects', () => { + @jsonObject + class WithRawSet { + @jsonSetMember(() => AnyT) + rawSet: Set; + } + + function rawObjects() { + return [ + { + prop: 'something', + }, + { + another: 'value', + }, + ]; + } + + it('should deserialize as is', () => { + const withRawSet = TypedJSON.parse({rawSet: rawObjects()}, WithRawSet); + expect(withRawSet).toBeDefined(); + expect(withRawSet instanceof WithRawSet).toBeTruthy(); + expect(withRawSet.rawSet).toEqual(new Set(rawObjects())); + }); + + it('should serialize as is', () => { + const withRawSet = new WithRawSet(); + withRawSet.rawSet = new Set(rawObjects()); + const json = TypedJSON.toPlainJson(withRawSet, WithRawSet); + expect(json).toEqual({rawSet: rawObjects()}); + }); +}); diff --git a/spec/lazy-types/to-json.spec.ts b/spec/lazy-types/to-json.spec.ts new file mode 100644 index 0000000..f0beb7c --- /dev/null +++ b/spec/lazy-types/to-json.spec.ts @@ -0,0 +1,95 @@ +import {jsonMember, jsonObject, toJson} from '../../src'; + +describe('lazy, toJson decorator', () => { + it('should work with JSON.stringify', () => { + @toJson + @jsonObject + class Person { + firstName?: string; + + @jsonMember({name: 'surname'}) + lastName?: string; + + getFullName() { + return `${this.firstName} ${this.lastName}`; + } + } + + const person = new Person(); + person.firstName = 'John'; + person.lastName = 'Doe'; + expect(JSON.stringify(person)).toBe('{"surname":"Doe"}'); + }); + + it('should work on the abstract class', () => { + @toJson + abstract class Base { + @jsonMember({name: 'renamed'}) + prop?: string; + } + + @jsonObject + class Sub extends Base { + @jsonMember({name: 'numeric'}) + num?: number; + } + + @jsonObject + class OtherSub extends Base { + @jsonMember + decimal?: number; + ignored?: string; + } + + const sub = new Sub(); + sub.prop = 'value'; + sub.num = 20; + expect(JSON.stringify(sub)).toBe('{"renamed":"value","numeric":20}'); + + const otherSub = new OtherSub(); + otherSub.prop = 'value'; + otherSub.decimal = 123; + otherSub.ignored = 'assigned'; + expect(JSON.stringify(otherSub)).toBe('{"renamed":"value","decimal":123}'); + }); + + it('should throw an error when toJSON already exists', () => { + try { + @toJson + @jsonObject + class Some { + @jsonMember + prop?: string; + + toJSON() { + return {}; + } + } + + const some = new Some(); + some.prop = 'value'; + expect(JSON.stringify(some)).toBe('{}'); + + fail('Should not succeed'); + } catch (error) { + // ok + } + }); + + it('should overwrite toJSON when overwrite is true', () => { + @toJson({overwrite: true}) + @jsonObject + class Some { + @jsonMember + prop?: string; + + toJSON() { + return {}; + } + } + + const some = new Some(); + some.prop = 'value'; + expect(JSON.stringify(some)).toBe('{"prop":"value"}'); + }); +}); diff --git a/spec/map.spec.ts b/spec/map.spec.ts new file mode 100644 index 0000000..3e22643 --- /dev/null +++ b/spec/map.spec.ts @@ -0,0 +1,151 @@ +import {ArrayT, jsonMapMember} from '../src'; +import {jsonMember} from '../src/json-member'; +import {jsonObject} from '../src/json-object'; +import {TypedJSON} from '../src/parser'; +import {MapShape} from '../src/type-descriptor'; + +describe('map dictionary shape', () => { + @jsonObject + class Simple { + @jsonMember + strProp: string; + + @jsonMember + numProp: number; + + constructor(init?: {strProp: string; numProp: number}) { + if (init !== undefined) { + this.strProp = init.strProp; + this.numProp = init.numProp; + } + } + + foo() { + return `${this.strProp}-${this.numProp}`; + } + } + + @jsonObject + class DictMap { + @jsonMapMember(String, Simple, {shape: MapShape.OBJECT}) + prop: Map; + + getSetSize() { + return this.prop.size; + } + } + + it('deserializes', () => { + const result = TypedJSON.parse( + JSON.stringify( + { + prop: { + one: {strProp: 'delta', numProp: 4}, + two: {strProp: 'gamma', numProp: 7}, + }, + }, + ), + DictMap, + ); + + expect(result).toBeInstanceOf(DictMap); + expect(result.prop).toBeDefined(); + expect(result.prop).toBeInstanceOf(Map); + expect(result.prop.size).toBe(2); + expect(result.getSetSize()).toBe(2); + expect(result.prop.get('one').strProp).toBe('delta'); + expect(result.prop.get('two').strProp).toBe('gamma'); + }); + + it('serializes', () => { + const object = new DictMap(); + object.prop = new Map([ + ['one', new Simple({strProp: 'delta', numProp: 4})], + ['two', new Simple({strProp: 'gamma', numProp: 7})], + ]); + const result = TypedJSON.stringify(object, DictMap); + + expect(result).toBe(JSON.stringify({ + prop: { + one: {strProp: 'delta', numProp: 4}, + two: {strProp: 'gamma', numProp: 7}, + }, + })); + }); +}); + +describe('map of array dictionary shape', () => { + @jsonObject + class Simple { + @jsonMember + strProp: string; + + @jsonMember + numProp: number; + + constructor(init?: {strProp: string; numProp: number}) { + if (init !== undefined) { + this.strProp = init.strProp; + this.numProp = init.numProp; + } + } + + foo() { + return `${this.strProp}-${this.numProp}`; + } + } + + @jsonObject + class DictArrayMap { + @jsonMapMember(String, ArrayT(Simple), {shape: MapShape.OBJECT}) + prop: Map>; + + getSetSize() { + return this.prop.size; + } + } + + it('deserializes', () => { + const result = TypedJSON.parse( + JSON.stringify( + { + prop: { + one: [{strProp: 'delta', numProp: 4}], + two: [{strProp: 'gamma', numProp: 7}, {strProp: 'alpha', numProp: 2}], + }, + }, + ), + DictArrayMap, + ); + + expect(result).toBeInstanceOf(DictArrayMap); + expect(result.prop).toBeDefined(); + expect(result.prop).toBeInstanceOf(Map); + expect(result.prop.size).toBe(2); + expect(result.getSetSize()).toBe(2); + expect(result.prop.get('one').length).toBe(1); + expect(result.prop.get('one')[0].foo()).toBe('delta-4'); + expect(result.prop.get('two').length).toBe(2); + expect(result.prop.get('two')[0].foo()).toBe('gamma-7'); + expect(result.prop.get('two')[1].foo()).toBe('alpha-2'); + }); + + it('serializes', () => { + const object = new DictArrayMap(); + object.prop = new Map>([ + ['one', [new Simple({strProp: 'delta', numProp: 4})]], + ['two', [ + new Simple({strProp: 'gamma', numProp: 7}), + new Simple({strProp: 'alpha', numProp: 2}), + ]], + ]); + const result = TypedJSON.stringify(object, DictArrayMap); + + expect(result).toBe(JSON.stringify({ + prop: { + one: [{strProp: 'delta', numProp: 4}], + two: [{strProp: 'gamma', numProp: 7}, {strProp: 'alpha', numProp: 2}], + }, + })); + }); +}); diff --git a/spec/mapped-types.spec.ts b/spec/mapped-types.spec.ts new file mode 100644 index 0000000..131e981 --- /dev/null +++ b/spec/mapped-types.spec.ts @@ -0,0 +1,261 @@ +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../src'; + +TypedJSON.setGlobalConfig({ + errorHandler: e => { + throw e; + }, +}); + +const date2000 = '2000-01-01T00:00:00.000Z'; +const date3000 = '3000-01-01T00:00:00.000Z'; + +describe('mapped types', () => { + class CustomType { + value: any; + + constructor(value: any) { + this.value = value; + } + + hasSucceeded(): boolean { + return this.value != null; + } + } + + @jsonObject + class MappedTypesSpec { + + @jsonMember + one: CustomType; + + @jsonMember + two: CustomType; + } + + const testData = { + one: 1, + two: 2, + }; + + describe('global', () => { + TypedJSON.mapType(CustomType, { + deserializer: json => new CustomType(json), + serializer: value => value.value, + }); + + it('deserializes', () => { + const result = TypedJSON.parse(testData, MappedTypesSpec); + + expect(result.one).toBeInstanceOf(CustomType); + expect(result.one.hasSucceeded()).toBeTrue(); + expect(result.two).toBeInstanceOf(CustomType); + expect(result.two.hasSucceeded()).toBeTrue(); + }); + + it('serializes', () => { + const test = new MappedTypesSpec(); + test.one = new CustomType(1); + test.two = new CustomType(2); + const result = TypedJSON.toPlainJson(test, MappedTypesSpec); + + expect(result).toEqual(testData); + }); + }); + + describe('instance', () => { + const typedJson = new TypedJSON(MappedTypesSpec); + typedJson.mapType(CustomType, { + deserializer: json => new CustomType(json), + serializer: value => value.value, + }); + + it('deserializes', () => { + const result = typedJson.parse(testData); + + expect(result.one).toBeInstanceOf(CustomType); + expect(result.one.hasSucceeded()).toBeTrue(); + expect(result.two).toBeInstanceOf(CustomType); + expect(result.two.hasSucceeded()).toBeTrue(); + }); + + it('serializes', () => { + const test = new MappedTypesSpec(); + test.one = new CustomType(1); + test.two = new CustomType(2); + const result = typedJson.toPlainJson(test); + + expect(result).toEqual(testData); + }); + }); + + describe('works with constructor,', () => { + @jsonObject + class MappedTypeWithConstructor { + + @jsonMember(CustomType) + nullable: any; + } + + const typedJson = new TypedJSON(MappedTypeWithConstructor); + const CustomTypeMap = { + deserializer: json => new CustomType(json), + serializer: value => value.value, + }; + typedJson.mapType(CustomType, CustomTypeMap); + + it('deserializes', () => { + spyOn(CustomTypeMap, 'deserializer').and.callThrough(); + const result = typedJson.parse({nullable: 5}); + expect(result.nullable?.hasSucceeded()).toBeTrue(); + expect(result.nullable?.value).toBe(5); + expect(CustomTypeMap.deserializer).toHaveBeenCalled(); + }); + + it('serializes', () => { + spyOn(CustomTypeMap, 'serializer').and.callThrough(); + const object = new MappedTypeWithConstructor(); + object.nullable = new CustomType(5); + const result = typedJson.toPlainJson(object); + expect(CustomTypeMap.serializer).toHaveBeenCalled(); + expect(result).toEqual({nullable: 5}); + }); + }); + + it('can be overwritten with deserializer/serializer prop', () => { + const jsonMemberOptions = { + deserializer: json => new CustomType(0), + serializer: value => 1, + }; + + const CustomTypeMap = { + deserializer: json => new CustomType(json), + serializer: value => value.value, + }; + + spyOn(CustomTypeMap, 'serializer').and.callThrough(); + spyOn(jsonMemberOptions, 'serializer').and.callThrough(); + spyOn(CustomTypeMap, 'deserializer').and.callThrough(); + spyOn(jsonMemberOptions, 'deserializer').and.callThrough(); + + @jsonObject + class OverriddenSerializer { + @jsonMember(jsonMemberOptions) + overwritten: CustomType; + + @jsonMember + simple: CustomType; + } + + const typedJson = new TypedJSON(OverriddenSerializer); + typedJson.mapType(CustomType, CustomTypeMap); + + const parsed = typedJson.parse({data: 5, simple: 5}); + expect(CustomTypeMap.deserializer).toHaveBeenCalledTimes(1); + expect(jsonMemberOptions.deserializer).toHaveBeenCalledTimes(1); + expect(parsed.overwritten.value).toBe(0); + expect(parsed.simple.value).toBe(5); + + const plain: any = typedJson.toPlainJson(parsed); + expect(CustomTypeMap.serializer).toHaveBeenCalledTimes(1); + expect(jsonMemberOptions.serializer).toHaveBeenCalledTimes(1); + expect(plain.overwritten).toBe(1); + expect(plain.simple).toBe(5); + }); + + it('should use default when only mapping deserializer', () => { + @jsonObject + class OnlyDeSerializer { + @jsonMember + date: Date; + } + + const typedJson = new TypedJSON(OnlyDeSerializer); + typedJson.mapType(Date, { + deserializer: value => new Date(new Date(value).setFullYear(3000)), + }); + + const parsed = typedJson.parse({date: date2000}); + + expect(parsed.date.toISOString()).toEqual(date3000); + expect((typedJson.toPlainJson(parsed) as any).date.toString()) + .toEqual(new Date(date3000).toString()); + }); + + it('should use default when only mapping serializer', () => { + @jsonObject + class OnlySerializer { + @jsonMember + date: Date; + } + + const typedJson = new TypedJSON(OnlySerializer); + typedJson.mapType(Date, { + serializer: value => new Date(value.setFullYear(3000)).toISOString(), + }); + + const test = new OnlySerializer(); + test.date = new Date(date2000); + const result = typedJson.toPlainJson(test); + + expect(result).toEqual({date: date3000}); + expect(typedJson.parse({date: date2000}).date.toISOString()).toEqual(date2000); + }); + + it('should handle mapping arrays', () => { + @jsonObject + class MappedTypeWithArray { + + @jsonArrayMember(String) + array: Array; + } + + const typedJson = new TypedJSON(MappedTypeWithArray); + const ArrayTypeMap = { + deserializer: json => ['deserialized'], + serializer: value => ['serialized'], + }; + + typedJson.mapType(Array, ArrayTypeMap); + + spyOn(ArrayTypeMap, 'serializer').and.callThrough(); + spyOn(ArrayTypeMap, 'deserializer').and.callThrough(); + const parsed = typedJson.parse({array: ['hello']}); + expect(ArrayTypeMap.deserializer).toHaveBeenCalled(); + expect(parsed.array).toEqual(['deserialized']); + + const plain: any = typedJson.toPlainJson(parsed); + expect(ArrayTypeMap.serializer).toHaveBeenCalled(); + expect(plain.array).toEqual(['serialized']); + }); + + it('works on arrays', () => { + @jsonObject + class MappedTypeWithArray { + + @jsonArrayMember(CustomType) + array: Array; + } + + const typedJson = new TypedJSON(MappedTypeWithArray); + const CustomTypeMap = { + deserializer: json => new CustomType(json), + serializer: value => value.value, + }; + typedJson.mapType(CustomType, CustomTypeMap); + + spyOn(CustomTypeMap, 'serializer').and.callThrough(); + spyOn(CustomTypeMap, 'deserializer').and.callThrough(); + const parsed = typedJson.parse({array: [1, 5]}); + expect(CustomTypeMap.deserializer).toHaveBeenCalled(); + expect(parsed.array.map(c => c.value)).toEqual([1, 5]); + + const plain: any = typedJson.toPlainJson(parsed); + expect(CustomTypeMap.serializer).toHaveBeenCalled(); + expect(plain.array).toEqual([1, 5]); + }); +}); + +TypedJSON.setGlobalConfig({ + errorHandler: () => undefined, +}); + diff --git a/spec/onDeserialized.spec.ts b/spec/on-deserialized.spec.ts similarity index 59% rename from spec/onDeserialized.spec.ts rename to spec/on-deserialized.spec.ts index ed57f48..fc852d0 100644 --- a/spec/onDeserialized.spec.ts +++ b/spec/on-deserialized.spec.ts @@ -1,10 +1,9 @@ -import { jsonObject, jsonMember, TypedJSON } from "../src/typedjson"; +import {jsonMember, jsonObject, TypedJSON} from '../src'; -describe('onDeserialized', function () { - - it('should call the static method', function() { +describe('onDeserialized', () => { + it('should call the static method', () => { @jsonObject({ - onDeserialized: 'afterDeser' + onDeserialized: 'afterDeser', }) class Person { @jsonMember @@ -13,25 +12,26 @@ describe('onDeserialized', function () { @jsonMember age: number; - public static afterDeser() { + static afterDeser() { // should call } - public getDescription() { - return this.name + " is " + this.age + "y old"; + getDescription() { + return `${this.name} is ${this.age}y old`; } } + spyOn(Person, 'afterDeser'); - const person = TypedJSON.parse({'name': 'John', age: 20}, Person)!; + const person = TypedJSON.parse({name: 'John', age: 20}, Person)!; expect(person instanceof Person).toBeTruthy(); expect(person.getDescription()).toEqual('John is 20y old'); expect(Person.afterDeser).toHaveBeenCalled(); }); - it('should call the member method', function() { + it('should call the member method', () => { @jsonObject({ - onDeserialized: 'afterDeser' + onDeserialized: 'afterDeser', }) class Person { @jsonMember @@ -44,24 +44,24 @@ describe('onDeserialized', function () { spyOn(this, 'afterDeser'); } - public afterDeser() { + afterDeser() { // should call } - public getDescription() { - return this.name + " is " + this.age + "y old"; + getDescription() { + return `${this.name} is ${this.age}y old`; } } - const person = TypedJSON.parse({'name': 'John', age: 20}, Person)!; + const person = TypedJSON.parse({name: 'John', age: 20}, Person)!; expect(person instanceof Person).toBeTruthy(); expect(person.getDescription()).toEqual('John is 20y old'); expect(person.afterDeser).toHaveBeenCalled(); }); - it('should prefer the member method when there are both', function() { + it('should prefer the member method when there are both', () => { @jsonObject({ - onDeserialized: 'afterDeser' + onDeserialized: 'afterDeser', }) class Person { @jsonMember @@ -70,25 +70,26 @@ describe('onDeserialized', function () { @jsonMember age: number; - public static afterDeser() { - // should NOT call - } - constructor() { spyOn(this, 'afterDeser'); } - public afterDeser() { + static afterDeser() { + // should NOT call + } + + afterDeser() { // should call } - public getDescription() { - return this.name + " is " + this.age + "y old"; + getDescription() { + return `${this.name} is ${this.age}y old`; } } + spyOn(Person, 'afterDeser'); - const person = TypedJSON.parse({'name': 'John', age: 20}, Person)!; + const person = TypedJSON.parse({name: 'John', age: 20}, Person)!; expect(person instanceof Person).toBeTruthy(); expect(person.getDescription()).toEqual('John is 20y old'); expect(person.afterDeser).toHaveBeenCalled(); diff --git a/spec/parse-to-object.spec.ts b/spec/parse-to-object.spec.ts index e16cbc5..aac315e 100644 --- a/spec/parse-to-object.spec.ts +++ b/spec/parse-to-object.spec.ts @@ -1,7 +1,7 @@ -import { parseToJSObject } from '../src/typedjson/helpers'; +import {parseToJSObject} from '../src/helpers'; -describe("parse To Object", function () { - it("should passthrough objects", function () { +describe('parse To Object', () => { + it('should passthrough objects', () => { const obj = { a: 1, b: 2, @@ -11,7 +11,7 @@ describe("parse To Object", function () { expect(obj2).toBe(obj); }); - it("should passthrough arrays", function () { + it('should passthrough arrays', () => { const arr = [{ a: 1, b: 2, @@ -21,7 +21,7 @@ describe("parse To Object", function () { expect(arr2).toBe(arr); }); - it("should parse object string", function () { + it('should parse object string', () => { const arr = { a: 1, b: 2, @@ -31,17 +31,18 @@ describe("parse To Object", function () { expect(arr2).toEqual(arr); }); - it("should passthrough primitives", function () { + it('should passthrough primitives', () => { expect(parseToJSObject(1, Number)).toBe(1); expect(parseToJSObject(false, Boolean)).toBe(false); }); - it("should parse strings with quotes, but passthrough other", function () { + it('should parse strings with quotes, but passthrough other', () => { // string is obvious expect(parseToJSObject('"I am a string"', String)).toEqual('I am a string'); expect(parseToJSObject('just a string', String)).toBe('just a string'); // but also the types that are serialized to string - expect(parseToJSObject('"1970-01-18T20:51:55.254Z"', Date)).toEqual('1970-01-18T20:51:55.254Z'); + expect(parseToJSObject('"1970-01-18T20:51:55.254Z"', Date)) + .toEqual('1970-01-18T20:51:55.254Z'); expect(parseToJSObject('1970-01-18T20:51:55.254Z', Date)).toBe('1970-01-18T20:51:55.254Z'); expect(parseToJSObject('"畤慰"', ArrayBuffer)).toEqual('畤慰'); expect(parseToJSObject('畤慰', ArrayBuffer)).toBe('畤慰'); @@ -49,10 +50,10 @@ describe("parse To Object", function () { expect(parseToJSObject('畤慰', DataView)).toBe('畤慰'); }); - it("should passthrough builtins", function () { - const date = new Date; - expect(parseToJSObject(date, Date)).toBe(date); - const buffer = new ArrayBuffer(3); - expect(parseToJSObject(buffer, ArrayBuffer)).toBe(buffer); + it('should passthrough builtins', () => { + const date = new Date(); + expect(parseToJSObject(date, Date)).toBe(date); + const buffer = new ArrayBuffer(3); + expect(parseToJSObject(buffer, ArrayBuffer)).toBe(buffer); }); }); diff --git a/spec/polymorphism-abstract-class.spec.ts b/spec/polymorphism-abstract-class.spec.ts index 7337c5a..23d5ffb 100644 --- a/spec/polymorphism-abstract-class.spec.ts +++ b/spec/polymorphism-abstract-class.spec.ts @@ -1,116 +1,116 @@ -import {isEqual} from "./utils/object-compare"; -import {TypedJSON, jsonObject, jsonMember, jsonArrayMember} from "../src/typedjson"; - -abstract class Node { - @jsonMember - name: string; -} - -@jsonObject -class SmallNode extends Node { - @jsonMember - inputType: string; - - @jsonMember - outputType: string; -} - -@jsonObject -class BigNode extends Node { - @jsonArrayMember(String) - inputs: string[]; - - @jsonArrayMember(String) - outputs: string[]; - - constructor() { - super(); - this.inputs = []; - this.outputs = []; - } -} +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../src'; +import {isEqual} from './utils/object-compare'; -@jsonObject({ - knownTypes: [BigNode, SmallNode] -}) -class Graph { - @jsonArrayMember(Node) - nodes: Node[]; +describe('polymorphic abstract classes', () => { + abstract class Node { + @jsonMember + name: string; + } - @jsonMember - root: Node; + @jsonObject + class SmallNode extends Node { + @jsonMember + inputType: string; - constructor() { - this.nodes = []; + @jsonMember + outputType: string; } -} - -function randPortType() { - var types = [ - "string", - "integer", - "float", - "boolean", - "void" - ]; - - return types[Math.floor(Math.random() * types.length)]; -} - -export function test(log: boolean) { - var graph = new Graph(); - - for (var i = 0; i < 20; i++) { - let node: Node; - - if (Math.random() < 0.25) { - let bigNode = new BigNode(); - - bigNode.inputs = [ - randPortType(), - randPortType(), - randPortType() - ]; - bigNode.outputs = [ - randPortType(), - randPortType() - ]; - - node = bigNode; - } else { - let smallNode = new SmallNode(); - - smallNode.inputType = randPortType(); - smallNode.outputType = randPortType(); - - node = smallNode; + + @jsonObject + class BigNode extends Node { + @jsonArrayMember(String) + inputs: Array; + + @jsonArrayMember(String) + outputs: Array; + + constructor() { + super(); + this.inputs = []; + this.outputs = []; } + } - node.name = `node_${i}`; + @jsonObject({ + knownTypes: [BigNode, SmallNode], + }) + class Graph { + @jsonArrayMember(Node) + nodes: Array; - if (i === 0) { - graph.root = node; - } else { - graph.nodes.push(node); + @jsonMember + root: Node; + + constructor() { + this.nodes = []; } } - var json = TypedJSON.stringify(graph, Graph); - var clone = TypedJSON.parse(json, Graph); + function randPortType() { + const types = [ + 'string', + 'integer', + 'float', + 'boolean', + 'void', + ]; - if (log) { - console.log("Test: polymorphism with abstract property types..."); - console.log(graph); - console.log(JSON.parse(json)); - console.log(clone); - console.log("Test finished."); + return types[Math.floor(Math.random() * types.length)]; } - return isEqual(graph, clone); -} + function test(log: boolean) { + const graph = new Graph(); + + for (let i = 0; i < 20; i++) { + let node: Node; + + if (Math.random() < 0.25) { + const bigNode = new BigNode(); + + bigNode.inputs = [ + randPortType(), + randPortType(), + randPortType(), + ]; + bigNode.outputs = [ + randPortType(), + randPortType(), + ]; + + node = bigNode; + } else { + const smallNode = new SmallNode(); + + smallNode.inputType = randPortType(); + smallNode.outputType = randPortType(); + + node = smallNode; + } + + node.name = `node_${i}`; + + if (i === 0) { + graph.root = node; + } else { + graph.nodes.push(node); + } + } + + const json = TypedJSON.stringify(graph, Graph); + const clone = TypedJSON.parse(json, Graph); + + if (log) { + console.log('Test: polymorphism with abstract property types...'); + console.log(graph); + console.log(JSON.parse(json)); + console.log(clone); + console.log('Test finished.'); + } + + return isEqual(graph, clone); + } -describe('polymorphic abstract classes', function() { - it('should work', function () { + it('should work', () => { expect(test(false)).toBeTruthy(); }); }); diff --git a/spec/polymorphism-custom-names.spec.ts b/spec/polymorphism-custom-names.spec.ts index 0808424..7399494 100644 --- a/spec/polymorphism-custom-names.spec.ts +++ b/spec/polymorphism-custom-names.spec.ts @@ -1,145 +1,147 @@ -import { isEqual } from "./utils/object-compare"; -import { jsonObject, jsonMember, jsonArrayMember, TypedJSON } from "../src/typedjson"; - -@jsonObject -class Person { - @jsonMember({ name: "first-name" }) - public firstName: string; - - @jsonMember({ name: "last-name" }) - public lastName: string; - - constructor(); - constructor(firstName: string, lastName: string); - constructor(firstName?: string, lastName?: string) { - if (firstName && lastName) { - this.firstName = firstName; - this.lastName = lastName; +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../src'; +import {isEqual} from './utils/object-compare'; + +describe('polymorphic custom names', () => { + @jsonObject + class Person { + @jsonMember({name: 'first-name'}) + firstName: string; + + @jsonMember({name: 'last-name'}) + lastName: string; + + constructor(firstName?: string, lastName?: string) { + if (firstName !== undefined && lastName !== undefined) { + this.firstName = firstName; + this.lastName = lastName; + } } } -} -@jsonObject -class Employee extends Person { - @jsonMember - public salary: number; + @jsonObject + class Employee extends Person { + @jsonMember + salary: number; - @jsonMember - public joined: Date; + @jsonMember + joined: Date; - constructor(); - constructor(firstName: string, lastName: string); - constructor(firstName: string, lastName: string, salary: number, joined: Date); - constructor(firstName?: string, lastName?: string, salary?: number, joined?: Date) { - super(firstName, lastName); + constructor(); + constructor(firstName: string, lastName: string); + constructor(firstName: string, lastName: string, salary: number, joined: Date); + constructor(firstName?: string, lastName?: string, salary?: number, joined?: Date) { + super(firstName, lastName); - if (salary && joined) { - this.salary = salary; - this.joined = joined; + if (salary !== undefined && joined !== undefined) { + this.salary = salary; + this.joined = joined; + } } } -} - -@jsonObject({ name: "part-time-employee" }) -class PartTimeEmployee extends Employee { - @jsonMember({ name: "work-hours" }) - public workHours: number; -} - -@jsonObject() -class Investor extends Person { - @jsonMember({ name: "invest-amount" }) - public investAmount: number; - - constructor(); - constructor(firstName: string, lastName: string); - constructor(firstName: string, lastName: string, investAmount: number); - constructor(firstName?: string, lastName?: string, investAmount?: number) { - super(firstName, lastName); - - this.investAmount = investAmount || 0; - } -} -@jsonObject({ name: "company", knownTypes: [PartTimeEmployee, Investor] }) -class Company { - @jsonMember - public name: string; + @jsonObject({name: 'part-time-employee'}) + class PartTimeEmployee extends Employee { + @jsonMember({name: 'work-hours'}) + workHours: number; + } - @jsonArrayMember(Employee, { name: 'company-employees' }) - public employees: Array; + @jsonObject() + class Investor extends Person { + @jsonMember({name: 'invest-amount'}) + investAmount: number; - @jsonMember - public owner: Person; + constructor(); + constructor(firstName: string, lastName: string, investAmount?: number); + constructor(firstName?: string, lastName?: string, investAmount?: number) { + super(firstName, lastName); - constructor() { - this.employees = []; - } -} - -export function test(log: boolean) { - // Create a Company. - var company = new Company(); - company.name = "Json Types"; - - switch (Math.floor(Math.random() * 4)) { - case 0: - company.owner = new Employee("John", "White", 240000, new Date(1992, 5, 27)); - break; - - case 1: - company.owner = new Investor("John", "White", 1700000); - break; - - case 2: - company.owner = new PartTimeEmployee("John", "White", 160000, new Date(1992, 5, 27)); - (company.owner as PartTimeEmployee).workHours = Math.floor(Math.random() * 40); - break; - - default: - company.owner = new Person("John", "White"); - break; + this.investAmount = investAmount ?? 0; + } } - // Add employees. - for (var j = 0; j < 20; j++) { - if (Math.random() < 0.2) { - var newPartTimeEmployee = new PartTimeEmployee( - `firstname_${j}`, - `lastname_${j}`, - Math.floor(Math.random() * 80000), - new Date(Date.now() - Math.floor(Math.random() * 80000)) - ); - - newPartTimeEmployee.workHours = Math.floor(Math.random() * 40); - - company.employees.push(newPartTimeEmployee); - } else { - company.employees.push(new Employee( - `firstname_${j}`, - `lastname_${j}`, - Math.floor(Math.random() * 80000), - new Date(Date.now() - Math.floor(Math.random() * 80000)) - )); + @jsonObject({name: 'company', knownTypes: [PartTimeEmployee, Investor]}) + class Company { + @jsonMember + name: string; + + @jsonArrayMember(Employee, {name: 'company-employees'}) + employees: Array; + + @jsonMember + owner: Person; + + constructor() { + this.employees = []; } } - var json = TypedJSON.stringify(company, Company); - var reparsed = TypedJSON.parse(json, Company); + function test(log: boolean) { + // Create a Company. + const company = new Company(); + company.name = 'Json Types'; + + switch (Math.floor(Math.random() * 4)) { + case 0: + company.owner = new Employee('John', 'White', 240000, new Date(1992, 5, 27)); + break; + + case 1: + company.owner = new Investor('John', 'White', 1700000); + break; + + case 2: + company.owner = new PartTimeEmployee( + 'John', + 'White', + 160000, + new Date(1992, 5, 27), + ); + (company.owner as PartTimeEmployee).workHours = Math.floor(Math.random() * 40); + break; + + default: + company.owner = new Person('John', 'White'); + break; + } - if (log) { - console.log("Test: polymorphism with custom names..."); - console.log(company); - console.log(JSON.parse(json)); - console.log(reparsed); - console.log("Test finished."); - } + // Add employees. + for (let j = 0; j < 20; j++) { + if (Math.random() < 0.2) { + const newPartTimeEmployee = new PartTimeEmployee( + `firstname_${j}`, + `lastname_${j}`, + Math.floor(Math.random() * 80000), + new Date(Date.now() - Math.floor(Math.random() * 80000)), + ); + + newPartTimeEmployee.workHours = Math.floor(Math.random() * 40); + + company.employees.push(newPartTimeEmployee); + } else { + company.employees.push(new Employee( + `firstname_${j}`, + `lastname_${j}`, + Math.floor(Math.random() * 80000), + new Date(Date.now() - Math.floor(Math.random() * 80000)), + )); + } + } + + const json = TypedJSON.stringify(company, Company); + const reparsed = TypedJSON.parse(json, Company); - return isEqual(company, reparsed); -} + if (log) { + console.log('Test: polymorphism with custom names...'); + console.log(company); + console.log(JSON.parse(json)); + console.log(reparsed); + console.log('Test finished.'); + } + + return isEqual(company, reparsed); + } -describe('polymorphic custom names', function() { - it('should work', function () { + it('should work', () => { expect(test(false)).toBeTruthy(); }); }); diff --git a/spec/polymorphism-custom-type-hints.spec.ts b/spec/polymorphism-custom-type-hints.spec.ts new file mode 100644 index 0000000..0d2c27c --- /dev/null +++ b/spec/polymorphism-custom-type-hints.spec.ts @@ -0,0 +1,316 @@ +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../src'; +import {IndexedObject} from '../src/types'; + +describe('polymorphism custom type hints', () => { + describe('should work for a base class', () => { + @jsonObject({ + typeHintEmitter: (targetObject, sourceObject) => { + targetObject.personType = `${sourceObject.constructor.name}Type`; + }, + typeResolver: sourceObject => TYPE_MAP[sourceObject.personType], + }) + abstract class Person { + @jsonMember + firstName: string; + + @jsonMember + lastName: string; + + constructor(firstName?: string, lastName?: string); + constructor(firstName: string, lastName: string); + constructor(firstName?: string, lastName?: string) { + if (firstName !== undefined && lastName !== undefined) { + this.firstName = firstName; + this.lastName = lastName; + } + } + } + + @jsonObject + class Employee extends Person { + @jsonMember + salary: number; + + constructor(); + constructor(firstName: string, lastName: string, salary?: number); + constructor(firstName?: string, lastName?: string, salary?: number) { + super(firstName, lastName); + + if (salary !== undefined) { + this.salary = salary; + } + } + } + + @jsonObject + class PartTimeEmployee extends Employee { + @jsonMember + workHours: number; + } + + @jsonObject + class Investor extends Person { + @jsonMember + investAmount: number; + + constructor(); + constructor(firstName: string, lastName: string, investAmount?: number); + constructor(firstName?: string, lastName?: string, investAmount?: number) { + super(firstName, lastName); + + this.investAmount = investAmount ?? 0; + } + } + + const TYPE_MAP: IndexedObject = { + EmployeeType: Employee, + PartTimeEmployeeType: PartTimeEmployee, + InvestorType: Investor, + }; + + @jsonObject + class Company { + @jsonMember + name: string; + + @jsonArrayMember(Employee) + employees: Array = []; + + @jsonMember + owner: Person; + } + + it('should emit custom hint', () => { + const company = new Company(); + company.name = 'Json Types'; + company.owner = new Investor('John', 'White', 1700000); + + const partTime = new PartTimeEmployee('Abe', 'White', 160000); + partTime.workHours = 20; + company.employees = [ + new Employee('Donn', 'Worker', 240000), + partTime, + new Employee('Smith', 'Elly', 35500), + ]; + + const json = TypedJSON.toPlainJson(company, Company); + expect(json).toEqual({ + name: 'Json Types', + owner: { + personType: 'InvestorType', + firstName: 'John', + lastName: 'White', + investAmount: 1700000, + }, + employees: [ + { + personType: 'EmployeeType', + firstName: 'Donn', + lastName: 'Worker', + salary: 240000, + }, + { + personType: 'PartTimeEmployeeType', + firstName: 'Abe', + lastName: 'White', + salary: 160000, + workHours: 20, + }, + { + personType: 'EmployeeType', + firstName: 'Smith', + lastName: 'Elly', + salary: 35500, + }, + ], + }); + }); + + it('should resolve custom hints', () => { + const json = { + name: 'Json Types', + owner: { + personType: 'InvestorType', + firstName: 'John', + lastName: 'White', + investAmount: 1700000, + }, + employees: [ + { + personType: 'EmployeeType', + firstName: 'Donn', + lastName: 'Worker', + salary: 240000, + }, + { + personType: 'PartTimeEmployeeType', + firstName: 'Abe', + lastName: 'White', + salary: 160000, + workHours: 20, + }, + { + personType: 'EmployeeType', + firstName: 'Smith', + lastName: 'Elly', + salary: 35500, + }, + ], + }; + + const deserialized = TypedJSON.parse(JSON.stringify(json), Company); + + const company = new Company(); + company.name = 'Json Types'; + company.owner = new Investor('John', 'White', 1700000); + + const partTime = new PartTimeEmployee('Abe', 'White', 160000); + partTime.workHours = 20; + company.employees = [ + new Employee('Donn', 'Worker', 240000), + partTime, + new Employee('Smith', 'Elly', 35500), + ]; + expect(deserialized).toEqual(company); + }); + }); + + describe('should override parents', () => { + abstract class StructuralBase { + @jsonMember + value: string; + } + + @jsonObject({ + typeHintEmitter: (targetObject, sourceObject) => { + targetObject.type = (sourceObject.constructor as any).type; + }, + typeResolver: sourceObject => { + return sourceObject.type === 'sub-one' ? ConcreteOne : AnotherConcreteOne; + }, + }) + abstract class SemanticBaseOne extends StructuralBase { + @jsonMember + prop1: number; + } + + @jsonObject + class ConcreteOne extends SemanticBaseOne { + static type = 'sub-one'; + @jsonMember + propSub: string; + } + + @jsonObject + class AnotherConcreteOne extends SemanticBaseOne { + static type = 'sub-two'; + @jsonMember + propSub: number; + } + + @jsonObject({ + typeHintEmitter: (targetObject, sourceObject) => { + targetObject.hint = sourceObject instanceof ConcreteTwo ? 'first' : 'another'; + }, + typeResolver: sourceObject => { + return sourceObject.hint === 'first' ? ConcreteTwo : AnotherConcreteTwo; + }, + }) + abstract class SemanticBaseTwo extends StructuralBase { + @jsonMember + prop2: number; + } + + @jsonObject + class ConcreteTwo extends SemanticBaseTwo { + @jsonMember + propSub: string; + } + + @jsonObject + class AnotherConcreteTwo extends SemanticBaseTwo { + @jsonMember + propSub: number; + } + + it('should work for SemanticBaseOne', () => { + const inputAndResult: Array<[() => SemanticBaseOne, () => IndexedObject]> = [ + [ + () => { + const expected = new ConcreteOne(); + expected.value = 'base'; + expected.prop1 = 10; + expected.propSub = 'something'; + return expected; + }, + () => ({ + type: 'sub-one', + value: 'base', + prop1: 10, + propSub: 'something', + }), + ], + [ + () => { + const expected = new AnotherConcreteOne(); + expected.value = 'base value'; + expected.prop1 = 245; + expected.propSub = 234; + return expected; + }, + () => ({ + type: 'sub-two', + value: 'base value', + prop1: 245, + propSub: 234, + }), + ], + ]; + + inputAndResult.forEach(([inputFn, serializedFn]) => { + expect(TypedJSON.toPlainJson(inputFn(), SemanticBaseOne)).toEqual(serializedFn()); + expect(TypedJSON.parse(serializedFn(), SemanticBaseOne)).toEqual(inputFn()); + }); + }); + + it('should work for SemanticBaseTwo', () => { + const inputAndResult: Array<[() => SemanticBaseTwo, () => IndexedObject]> = [ + [ + () => { + const expected = new ConcreteTwo(); + expected.value = 'base'; + expected.prop2 = 546; + expected.propSub = 'something'; + return expected; + }, + () => ({ + hint: 'first', + value: 'base', + prop2: 546, + propSub: 'something', + }), + ], + [ + () => { + const expected = new AnotherConcreteTwo(); + expected.value = 'base value'; + expected.prop2 = 74; + expected.propSub = 234; + return expected; + }, + () => ({ + hint: 'another', + value: 'base value', + prop2: 74, + propSub: 234, + }), + ], + ]; + + inputAndResult.forEach(([inputFn, serializedFn]) => { + expect(TypedJSON.toPlainJson(inputFn(), SemanticBaseTwo)).toEqual(serializedFn()); + expect(TypedJSON.parse(serializedFn(), SemanticBaseTwo)).toEqual(inputFn()); + }); + }); + }); +}); diff --git a/spec/polymorphism-interface.spec.ts b/spec/polymorphism-interface.spec.ts index da20686..4ea400e 100644 --- a/spec/polymorphism-interface.spec.ts +++ b/spec/polymorphism-interface.spec.ts @@ -1,128 +1,128 @@ -import {isEqual} from "./utils/object-compare"; -import {jsonObject, jsonMember, jsonArrayMember, TypedJSON} from "../src/typedjson"; +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../src'; +import {isEqual} from './utils/object-compare'; -interface Point { - x: number; - y: number; -} +describe('polymorphic interfaces', () => { + interface Point { + x: number; + y: number; + } -@jsonObject -class SmallNode implements Point { - @jsonMember - x: number; + @jsonObject + class SmallNode implements Point { + @jsonMember + x: number; - @jsonMember - y: number; + @jsonMember + y: number; - @jsonMember - inputType: string; + @jsonMember + inputType: string; - @jsonMember - outputType: string; -} + @jsonMember + outputType: string; + } -@jsonObject -class BigNode implements Point { - @jsonMember - x: number; + @jsonObject + class BigNode implements Point { + @jsonMember + x: number; - @jsonMember - y: number; + @jsonMember + y: number; - @jsonArrayMember(String) - inputs: string[]; + @jsonArrayMember(String) + inputs: Array; - @jsonArrayMember(String) - outputs: string[]; + @jsonArrayMember(String) + outputs: Array; - constructor() { - this.inputs = []; - this.outputs = []; + constructor() { + this.inputs = []; + this.outputs = []; + } } -} -@jsonObject({ - knownTypes: [BigNode, SmallNode] -}) -class GraphGrid { - @jsonArrayMember(Object) - points: Point[]; + @jsonObject({ + knownTypes: [BigNode, SmallNode], + }) + class GraphGrid { + @jsonArrayMember(Object) + points: Array; - @jsonMember - root: Point; + @jsonMember + root: Point; - constructor() { - this.points = []; - } -} - -function randPortType() { - var types = [ - "string", - "integer", - "float", - "boolean", - "void" - ]; - - return types[Math.floor(Math.random() * types.length)]; -} - -export function test(log: boolean) { - var graph = new GraphGrid(); - - for (var i = 0; i < 20; i++) { - let point: Point; - - if (Math.random() < 0.25) { - let bigNode = new BigNode(); - - bigNode.inputs = [ - randPortType(), - randPortType(), - randPortType() - ]; - bigNode.outputs = [ - randPortType(), - randPortType() - ]; - - point = bigNode; - } else { - let smallNode = new SmallNode(); - - smallNode.inputType = randPortType(); - smallNode.outputType = randPortType(); - - point = smallNode; + constructor() { + this.points = []; } + } - point.x = Math.random(); - point.y = Math.random(); + function randPortType() { + const types = [ + 'string', + 'integer', + 'float', + 'boolean', + 'void', + ]; - if (i === 0) { - graph.root = point; - } else { - graph.points.push(point); - } + return types[Math.floor(Math.random() * types.length)]; } - var json = TypedJSON.stringify(graph, GraphGrid); - var clone = TypedJSON.parse(json, GraphGrid); + function test(log: boolean) { + const graph = new GraphGrid(); - if (log) { - console.log("Test: polymorphism with interface property types..."); - console.log(graph); - console.log(JSON.parse(json)); - console.log(clone); - console.log("Test finished."); - } + for (let i = 0; i < 20; i++) { + let point: Point; + + if (Math.random() < 0.25) { + const bigNode = new BigNode(); + + bigNode.inputs = [ + randPortType(), + randPortType(), + randPortType(), + ]; + bigNode.outputs = [ + randPortType(), + randPortType(), + ]; + + point = bigNode; + } else { + const smallNode = new SmallNode(); - return isEqual(graph, clone); -} + smallNode.inputType = randPortType(); + smallNode.outputType = randPortType(); + + point = smallNode; + } + + point.x = Math.random(); + point.y = Math.random(); + + if (i === 0) { + graph.root = point; + } else { + graph.points.push(point); + } + } + + const json = TypedJSON.stringify(graph, GraphGrid); + const clone = TypedJSON.parse(json, GraphGrid); + + if (log) { + console.log('Test: polymorphism with interface property types...'); + console.log(graph); + console.log(JSON.parse(json)); + console.log(clone); + console.log('Test finished.'); + } + + return isEqual(graph, clone); + } -describe('polymorphic interfaces', function() { - it('should work', function () { + it('should work', () => { expect(test(false)).toBeTruthy(); }); }); diff --git a/spec/polymorphism-nested-arrays.spec.ts b/spec/polymorphism-nested-arrays.spec.ts index ca82994..71c7168 100644 --- a/spec/polymorphism-nested-arrays.spec.ts +++ b/spec/polymorphism-nested-arrays.spec.ts @@ -1,133 +1,133 @@ -import {isEqual} from "./utils/object-compare"; -import {jsonObject, jsonMember, jsonArrayMember, TypedJSON} from "../src/typedjson"; - -abstract class Node { - @jsonMember - name: string; -} - -@jsonObject -class SmallNode extends Node { - @jsonMember - inputType: string; - - @jsonMember - outputType: string; -} - -@jsonObject -class BigNode extends Node { - @jsonArrayMember(String) - inputs: string[]; - - @jsonArrayMember(String) - outputs: string[]; - - constructor() { - super(); - this.inputs = []; - this.outputs = []; - } -} +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../src'; +import {isEqual} from './utils/object-compare'; -@jsonObject({ knownTypes: [BigNode, SmallNode] }) -class Graph { - @jsonArrayMember(Node, {dimensions: 2}) - items: Array>; +describe('polymorphism in nested arrays', () => { + abstract class Node { + @jsonMember + name: string; + } - @jsonArrayMember(SmallNode, {dimensions: 2}) - smallItems: Array>; + @jsonObject + class SmallNode extends Node { + @jsonMember + inputType: string; - constructor() { - this.items = []; - this.smallItems = []; + @jsonMember + outputType: string; } -} - -function randPortType() { - var types = [ - "string", - "integer", - "float", - "boolean", - "void" - ]; - return types[Math.floor(Math.random() * types.length)]; -} + @jsonObject + class BigNode extends Node { + @jsonArrayMember(String) + inputs: Array; -export function test(log: boolean) { - var graph = new Graph(); + @jsonArrayMember(String) + outputs: Array; - for (var i = 0; i < 20; i++) { - graph.smallItems.push([]); + constructor() { + super(); + this.inputs = []; + this.outputs = []; + } + } - for (var j = 0; j < 8; j++) { - let node = new SmallNode(); + @jsonObject({knownTypes: [BigNode, SmallNode]}) + class Graph { + @jsonArrayMember(Node, {dimensions: 2}) + items: Array>; - node.name = `smallnode_${i}_${j}`; - node.inputType = randPortType(); - node.outputType = randPortType(); + @jsonArrayMember(SmallNode, {dimensions: 2}) + smallItems: Array>; - graph.smallItems[i].push(node); + constructor() { + this.items = []; + this.smallItems = []; } } - for (var i = 0; i < 20; i++) { - graph.items.push([]); + function randPortType() { + const types = [ + 'string', + 'integer', + 'float', + 'boolean', + 'void', + ]; - for (var j = 0; j < 8; j++) { - let node: Node; + return types[Math.floor(Math.random() * types.length)]; + } - if (Math.random() < 0.25) { - let bigNode = new BigNode(); + function test(log: boolean) { + const graph = new Graph(); - bigNode.inputs = [ - randPortType(), - randPortType(), - randPortType() - ]; - bigNode.outputs = [ - randPortType(), - randPortType() - ]; + for (let i = 0; i < 20; i++) { + graph.smallItems.push([]); - node = bigNode; - } else { - let smallNode = new SmallNode(); + for (let j = 0; j < 8; j++) { + const node = new SmallNode(); - smallNode.inputType = randPortType(); - smallNode.outputType = randPortType(); + node.name = `smallnode_${i}_${j}`; + node.inputType = randPortType(); + node.outputType = randPortType(); - node = smallNode; + graph.smallItems[i].push(node); } + } + + for (let i = 0; i < 20; i++) { + graph.items.push([]); + + for (let j = 0; j < 8; j++) { + let node: Node; + + if (Math.random() < 0.25) { + const bigNode = new BigNode(); + + bigNode.inputs = [ + randPortType(), + randPortType(), + randPortType(), + ]; + bigNode.outputs = [ + randPortType(), + randPortType(), + ]; - node.name = `node_${i}_${j}`; + node = bigNode; + } else { + const smallNode = new SmallNode(); - graph.items[i].push(node); + smallNode.inputType = randPortType(); + smallNode.outputType = randPortType(); + + node = smallNode; + } + + node.name = `node_${i}_${j}`; + + graph.items[i].push(node); + } } - } - var json = TypedJSON.stringify(graph, Graph); + const json = TypedJSON.stringify(graph, Graph); - if (log) { - console.log("Test: polymorphism with nested arrays..."); - console.log(graph); - console.log(JSON.parse(json)); - } + if (log) { + console.log('Test: polymorphism with nested arrays...'); + console.log(graph); + console.log(JSON.parse(json)); + } - var clone = TypedJSON.parse(json, Graph); + const clone = TypedJSON.parse(json, Graph); - if (log) { - console.log(clone); - console.log("Test finished."); - } + if (log) { + console.log(clone); + console.log('Test finished.'); + } - return isEqual(graph, clone); -} + return isEqual(graph, clone); + } -describe('polymorphism in nested arrays', function() { - it('should work', function () { + it('should work', () => { expect(test(false)).toBeTruthy(); }); }); diff --git a/spec/polymorphism-root-abstract-class.spec.ts b/spec/polymorphism-root-abstract-class.spec.ts index 5e10b73..0a4053d 100644 --- a/spec/polymorphism-root-abstract-class.spec.ts +++ b/spec/polymorphism-root-abstract-class.spec.ts @@ -1,7 +1,6 @@ -import { jsonObject, jsonMember, TypedJSON } from "../src/typedjson"; - -describe('single class', function () { +import {jsonMember, jsonObject, TypedJSON} from '../src'; +describe('single class', () => { abstract class Person { @jsonMember firstName?: string; @@ -9,8 +8,8 @@ describe('single class', function () { @jsonMember lastName?: string; - public getFullName() { - return this.firstName + " " + this.lastName; + getFullName() { + return `${this.firstName} ${this.lastName}`; } } @@ -19,18 +18,20 @@ describe('single class', function () { @jsonMember pounds?: number; - public getFullName() { - return super.getFullName() + ` weighing ${this.pounds}`; + getFullName() { + return `${super.getFullName()} weighing ${this.pounds}`; } } // todo we need something better - jsonObject({ knownTypes: [Bob]})(Person as any); + jsonObject({knownTypes: [Bob]})(Person); - describe('deserialized', function () { + describe('deserialized', () => { beforeAll(function () { - // todo fix types so they accept abstract - this.person = TypedJSON.parse('{ "__type": "Bob", "firstName": "John", "lastName": "Doe", "pounds": 40 }', Person as any); + this.person = TypedJSON.parse( + '{ "__type": "Bob", "firstName": "John", "lastName": "Doe", "pounds": 40 }', + Person, + ); }); it('should be of proper type', function () { @@ -43,14 +44,14 @@ describe('single class', function () { }); }); - describe('serialized', function () { - it('should contain all data', function () { - const person = new Bob; + describe('serialized', () => { + it('should contain all data', () => { + const person = new Bob(); person.firstName = 'John'; person.lastName = 'Doe'; person.pounds = 30; // todo fix types so they accept abstract - expect(TypedJSON.stringify(person, Person as any)) + expect(TypedJSON.stringify(person, Person)) .toBe('{"firstName":"John","lastName":"Doe","pounds":30,"__type":"Bob"}'); }); }); diff --git a/spec/polymorphism.spec.ts b/spec/polymorphism.spec.ts index f093a24..6a0fd6e 100644 --- a/spec/polymorphism.spec.ts +++ b/spec/polymorphism.spec.ts @@ -1,145 +1,149 @@ -import {isEqual} from "./utils/object-compare"; -import {jsonObject, jsonMember, jsonArrayMember, TypedJSON} from "../src/typedjson"; - -@jsonObject -class Person { - @jsonMember - public firstName: string; - - @jsonMember - public lastName: string; - - constructor(); - constructor(firstName: string, lastName: string); - constructor(firstName?: string, lastName?: string) { - if (firstName && lastName) { - this.firstName = firstName; - this.lastName = lastName; +import {jsonArrayMember, jsonMember, jsonObject, TypedJSON} from '../src'; +import {isEqual} from './utils/object-compare'; + +describe('polymorphism', () => { + @jsonObject + class Person { + @jsonMember + firstName: string; + + @jsonMember + lastName: string; + + constructor(); + constructor(firstName: string, lastName: string); + constructor(firstName?: string, lastName?: string) { + if (firstName !== undefined && lastName !== undefined) { + this.firstName = firstName; + this.lastName = lastName; + } } } -} -@jsonObject -class Employee extends Person { - @jsonMember - public salary: number; + @jsonObject + class Employee extends Person { + @jsonMember + salary: number; - @jsonMember - public joined: Date; + @jsonMember + joined: Date; - constructor(); - constructor(firstName: string, lastName: string); - constructor(firstName: string, lastName: string, salary: number, joined: Date); - constructor(firstName?: string, lastName?: string, salary?: number, joined?: Date) { - super(firstName, lastName); + constructor(); + constructor(firstName: string, lastName: string); + constructor(firstName: string, lastName: string, salary: number, joined: Date); + constructor(firstName?: string, lastName?: string, salary?: number, joined?: Date) { + super(firstName, lastName); - if (salary && joined) { - this.salary = salary; - this.joined = joined; + if (salary !== undefined && joined !== undefined) { + this.salary = salary; + this.joined = joined; + } } } -} - -@jsonObject -class PartTimeEmployee extends Employee { - @jsonMember - public workHours: number; -} - -@jsonObject -class Investor extends Person { - @jsonMember - public investAmount: number; - - constructor(); - constructor(firstName: string, lastName: string); - constructor(firstName: string, lastName: string, investAmount: number); - constructor(firstName?: string, lastName?: string, investAmount?: number) { - super(firstName, lastName); - - this.investAmount = investAmount || 0; - } -} -@jsonObject({ knownTypes: [PartTimeEmployee, Investor] }) -class Company { - @jsonMember - public name: string; + @jsonObject + class PartTimeEmployee extends Employee { + @jsonMember + workHours: number; + } - @jsonArrayMember(Employee) - public employees: Array; + @jsonObject + class Investor extends Person { + @jsonMember + investAmount: number; - @jsonMember - public owner: Person; + constructor(); + constructor(firstName: string, lastName: string, investAmount?: number); + constructor(firstName?: string, lastName?: string, investAmount?: number) { + super(firstName, lastName); - constructor() { - this.employees = []; - } -} - -export function test(log: boolean) { - // Create a Company. - var company = new Company(); - company.name = "Json Types"; - - switch (Math.floor(Math.random() * 4)) { - case 0: - company.owner = new Employee("John", "White", 240000, new Date(1992, 5, 27)); - break; - - case 1: - company.owner = new Investor("John", "White", 1700000); - break; - - case 2: - company.owner = new PartTimeEmployee("John", "White", 160000, new Date(1992, 5, 27)); - (company.owner as PartTimeEmployee).workHours = Math.floor(Math.random() * 40); - break; - - default: - company.owner = new Person("John", "White"); - break; + this.investAmount = investAmount ?? 0; + } } - // Add employees. - for (var j = 0; j < 20; j++) { - if (Math.random() < 0.2) { - var newPartTimeEmployee = new PartTimeEmployee( - `firstname_${j}`, - `lastname_${j}`, - Math.floor(Math.random() * 80000), - new Date(Date.now() - Math.floor(Math.random() * 80000)) - ); - - newPartTimeEmployee.workHours = Math.floor(Math.random() * 40); - - company.employees.push(newPartTimeEmployee); - } else { - company.employees.push(new Employee( - `firstname_${j}`, - `lastname_${j}`, - Math.floor(Math.random() * 80000), - new Date(Date.now() - Math.floor(Math.random() * 80000)) - )); + @jsonObject({knownTypes: [PartTimeEmployee, Investor]}) + class Company { + @jsonMember + name: string; + + @jsonArrayMember(Employee) + employees: Array; + + @jsonMember + owner: Person; + + constructor() { + this.employees = []; } } - var json = TypedJSON.stringify(company, Company); - var reparsed = TypedJSON.parse(json, Company); + function test(log: boolean) { + // Create a Company. + const company = new Company(); + company.name = 'Json Types'; + + switch (Math.floor(Math.random() * 4)) { + case 0: + company.owner = new Employee('John', 'White', 240000, new Date(1992, 5, 27)); + break; + + case 1: + company.owner = new Investor('John', 'White', 1700000); + break; + + case 2: + company.owner = new PartTimeEmployee( + 'John', + 'White', + 160000, + new Date(1992, 5, 27), + ); + (company.owner as PartTimeEmployee).workHours = Math.floor(Math.random() * 40); + break; + + default: + company.owner = new Person('John', 'White'); + break; + } - if (log) { - console.log("Test: polymorphism..."); - console.log(company); - console.log(JSON.parse(json)); - console.log(reparsed); - console.log("Test finished."); - } + // Add employees. + for (let j = 0; j < 20; j++) { + if (Math.random() < 0.2) { + const newPartTimeEmployee = new PartTimeEmployee( + `firstname_${j}`, + `lastname_${j}`, + Math.floor(Math.random() * 80000), + new Date(Date.now() - Math.floor(Math.random() * 80000)), + ); + + newPartTimeEmployee.workHours = Math.floor(Math.random() * 40); + + company.employees.push(newPartTimeEmployee); + } else { + company.employees.push(new Employee( + `firstname_${j}`, + `lastname_${j}`, + Math.floor(Math.random() * 80000), + new Date(Date.now() - Math.floor(Math.random() * 80000)), + )); + } + } + + const json = TypedJSON.stringify(company, Company); + const reparsed = TypedJSON.parse(json, Company); - return isEqual(company, reparsed); -} + if (log) { + console.log('Test: polymorphism...'); + console.log(company); + console.log(JSON.parse(json)); + console.log(reparsed); + console.log('Test finished.'); + } + + return isEqual(company, reparsed); + } -describe('polymorphism', function() { - it('should work', function () { + it('should work', () => { expect(test(false)).toBeTruthy(); }); }); diff --git a/spec/preserveNull.spec.ts b/spec/preserve-null.spec.ts similarity index 67% rename from spec/preserveNull.spec.ts rename to spec/preserve-null.spec.ts index 803e69c..c7e3fea 100644 --- a/spec/preserveNull.spec.ts +++ b/spec/preserve-null.spec.ts @@ -1,17 +1,16 @@ -import { jsonObject, jsonMember, TypedJSON, jsonArrayMember, jsonMapMember } from "../src/typedjson"; +import {jsonArrayMember, jsonMapMember, jsonMember, jsonObject, TypedJSON} from '../src'; -describe('preserveNull', function () { - - it('should work globally', function() { +describe('preserveNull', () => { + it('should work globally', () => { TypedJSON.setGlobalConfig({preserveNull: true}); @jsonObject class Person { @jsonMember - name: string|null; + name: string | null; } - const input = new Person; + const input = new Person(); input.name = null; const json = TypedJSON.toPlainJson(input, Person); expect(json).toEqual({name: null}); @@ -19,18 +18,19 @@ describe('preserveNull', function () { const obj = TypedJSON.parse({name: null}, Person); expect(obj).toEqual(input); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore delete TypedJSON._globalConfig; }); - it('should work in settings', function() { + it('should work in settings', () => { @jsonObject class Person { @jsonMember - name: string|null; + name: string | null; } - const input = new Person; + const input = new Person(); input.name = null; const json = TypedJSON.toPlainJson(input, Person, {preserveNull: true}); expect(json).toEqual({name: null}); @@ -39,14 +39,14 @@ describe('preserveNull', function () { expect(obj).toEqual(input); }); - it('should work on class', function() { + it('should work on class', () => { @jsonObject({preserveNull: true}) class Person { @jsonMember - name: string|null; + name: string | null; } - const input = new Person; + const input = new Person(); input.name = null; const json = TypedJSON.toPlainJson(input, Person); expect(json).toEqual({name: null}); @@ -55,14 +55,14 @@ describe('preserveNull', function () { expect(obj).toEqual(input); }); - it('should work on member', function() { + it('should work on member', () => { @jsonObject class Person { @jsonMember({preserveNull: true}) - name: string|null; + name: string | null; } - const input = new Person; + const input = new Person(); input.name = null; const json = TypedJSON.toPlainJson(input, Person); expect(json).toEqual({name: null}); @@ -71,122 +71,129 @@ describe('preserveNull', function () { expect(obj).toEqual(input); }); - it('should override parser when more specific', function() { + it('should override parser when more specific', () => { @jsonObject class Person { @jsonMember({preserveNull: false}) - name?: string|null; + name?: string | null; } - const input = new Person; + const input = new Person(); input.name = null; const json = TypedJSON.toPlainJson(input, Person, {preserveNull: true}); expect(json).toEqual({}); const obj = TypedJSON.parse({name: null}, Person, {preserveNull: true}); - expect(obj).toEqual(new Person); + expect(obj).toEqual(new Person()); }); - it('should override class when more specific', function() { + it('should override class when more specific', () => { @jsonObject({preserveNull: true}) class Person { @jsonMember({preserveNull: false}) - name?: string|null; + name?: string | null; } - const input = new Person; + const input = new Person(); input.name = null; const json = TypedJSON.toPlainJson(input, Person); expect(json).toEqual({}); const obj = TypedJSON.parse({name: null}, Person); - expect(obj).toEqual(new Person); + expect(obj).toEqual(new Person()); }); - it('should not affect other properties', function() { + it('should not affect other properties', () => { @jsonObject class Person { @jsonMember({preserveNull: true}) - name: string|null; + name: string | null; @jsonMember - age: number|null; + age: number | null; } - const input = new Person; + const input = new Person(); input.name = null; input.age = null; const json = TypedJSON.stringify(input, Person); expect(json).toEqual('{"name":null}'); const obj = TypedJSON.parse({name: null, age: null}, Person); - const expected = new Person; + const expected = new Person(); expected.name = null; expect(obj).toEqual(expected); }); - it('should not affect inner jsonObjects when set from parent jsonObject', function() { + it('should not affect inner jsonObjects when set from parent jsonObject', () => { @jsonObject class Inner { @jsonMember - prop: string|null; + prop: string | null; } @jsonObject({preserveNull: true}) class Person { @jsonMember - name: string|null; + name: string | null; @jsonMember - inn: Inner = new Inner; + inn: Inner = new Inner(); } - const input = new Person; + const input = new Person(); input.name = null; input.inn.prop = null; const json = TypedJSON.stringify(input, Person); expect(json).toEqual('{"name":null,"inn":{}}'); const obj = TypedJSON.parse({name: null, inn: {prop: null}}, Person); - const expected = new Person; + const expected = new Person(); expected.name = null; expect(obj).toEqual(expected); }); - it('should preserve nulls in array', function() { + it('should preserve nulls in array', () => { @jsonObject class Person { @jsonArrayMember(String, {preserveNull: true}) - names: (string|null)[]; + names: Array; } const input = new Person(); input.names = [null, 'one', null, null, 'two', null]; const json = TypedJSON.stringify(input, Person); expect(json).toEqual('{"names":[null,"one",null,null,"two",null]}'); - const obj = TypedJSON.parse({names: [null,'one',null,null,'two',null]}, Person); + const obj = TypedJSON.parse({names: [null, 'one', null, null, 'two', null]}, Person); expect(obj).toEqual(input); }); - it('should preserve nulls in maps', function() { + it('should preserve nulls in maps', () => { @jsonObject class Person { @jsonMapMember(String, String, {preserveNull: true}) - map: Map; + map: Map; } const input = new Person(); - input.map = new Map([ + input.map = new Map([ ['one', null], ['two', null], ['three', 'val'], ]); const json = TypedJSON.stringify(input, Person); expect(json).toEqual( - '{"map":[{"key":"one","value":null},{"key":"two","value":null},{"key":"three","value":"val"}]}', + '{"map":[{"key":"one","value":null},{"key":"two","value":null},' + + '{"key":"three","value":"val"}]}', ); const obj = TypedJSON.parse( - {'map':[{'key':'one','value':null},{'key':'two','value':null},{'key':'three','value':'val'}]}, + { + map: [ + {key: 'one', value: null}, + {key: 'two', value: null}, + {key: 'three', value: 'val'}, + ], + }, Person, ); expect(obj).toEqual(input); diff --git a/spec/set.spec.ts b/spec/set.spec.ts index 4edf46e..39b8056 100644 --- a/spec/set.spec.ts +++ b/spec/set.spec.ts @@ -1,7 +1,7 @@ -import { jsonObject, jsonMember, jsonArrayMember, TypedJSON, jsonSetMember } from "../src/typedjson"; -import { Everything, IEverything } from "./utils/everything"; +import {ArrayT, jsonMember, jsonObject, jsonSetMember, SetT, TypedJSON} from '../src'; +import {Everything} from './utils/everything'; -describe('set of objects', function () { +describe('set of objects', () => { @jsonObject class Simple { @jsonMember @@ -10,32 +10,30 @@ describe('set of objects', function () { @jsonMember numProp: number; - constructor(init: { strProp: string, numProp: number }) - constructor() - constructor(init?: { strProp: string, numProp: number }) { - if (init) { + constructor(init?: {strProp: string; numProp: number}) { + if (init !== undefined) { this.strProp = init.strProp; this.numProp = init.numProp; } } - public foo() { + foo() { return `${this.strProp}-${this.numProp}`; } } - it('deserializes empty set', function () { + it('deserializes empty set', () => { const result = TypedJSON.parseAsSet('[]', Simple); expect(result).toBeDefined(); expect(result.size).toBe(0); }); - it('serialized empty set', function () { + it('serialized empty set', () => { const result = TypedJSON.stringifyAsSet(new Set(), Simple); expect(result).toBe('[]'); }); - it('deserialized should be of proper type', function () { + it('deserialized should be of proper type', () => { const expectation = [ {strProp: 'delta', numProp: 4}, {strProp: 'bravo', numProp: 2}, @@ -47,36 +45,39 @@ describe('set of objects', function () { expect(result.size).toBe(3, 'Deserialized set is of wrong size'); result.forEach((obj) => { expect(obj).toBeInstanceOf(Simple); - expect(obj).toHaveProperties(expectation.find((expected) => expected.strProp === obj.strProp)); + expect(obj) + .toHaveProperties(expectation.find((expected) => expected.strProp === obj.strProp)); }); }); - it('serialized should contain all elements', function () { + it('serialized should contain all elements', () => { const expectation = [ {strProp: 'delta', numProp: 4}, {strProp: 'bravo', numProp: 2}, {strProp: 'gamma', numProp: 0}, ]; - const result = TypedJSON.stringifyAsSet(new Set(expectation.map(obj => new Simple(obj))), Simple); + const set = new Set(expectation.map(obj => new Simple(obj))); + const result = TypedJSON.stringifyAsSet(set, Simple); expect(result).toBe(JSON.stringify(expectation)); }); }); -describe('set member', function () { +describe('set member', () => { @jsonObject class WithSet { @jsonSetMember(Everything) prop: Set; - public getSetSize() { + getSetSize() { return this.prop.size; } } - it('deserializes', function () { - const result = TypedJSON.parse(JSON.stringify({prop: [Everything.create(), Everything.create()]}), WithSet); + it('deserializes', () => { + const object = {prop: [Everything.create(), Everything.create()]}; + const result = TypedJSON.parse(JSON.stringify(object), WithSet); expect(result).toBeInstanceOf(WithSet); expect(result.prop).toBeDefined(); @@ -86,7 +87,7 @@ describe('set member', function () { expect(Array.from(result.prop)).toEqual([Everything.expected(), Everything.expected()]); }); - it('serializes', function () { + it('serializes', () => { const object = new WithSet(); object.prop = new Set([Everything.expected(), Everything.expected()]); const result = TypedJSON.stringify(object, WithSet); @@ -95,7 +96,110 @@ describe('set member', function () { }); }); -describe('set of raw objects', function () { +describe('set array member', () => { + @jsonObject + class Simple { + @jsonMember + strProp: string; + + @jsonMember + numProp: number; + + constructor(init?: {strProp: string; numProp: number}) { + if (init !== undefined) { + this.strProp = init.strProp; + this.numProp = init.numProp; + } + } + + foo() { + return `${this.strProp}-${this.numProp}`; + } + } + + @jsonObject + class WithSet { + @jsonMember({constructor: SetT(ArrayT(Simple))}) + prop: Set>; + + getSetSize() { + return this.prop.size; + } + } + + it('deserializes', () => { + const result = TypedJSON.parse( + JSON.stringify( + { + prop: [ + [ + {strProp: 'delta', numProp: 4}, + {strProp: 'bravo', numProp: 2}, + {strProp: 'gamma', numProp: 0}, + ], + [ + {strProp: 'alpha', numProp: 3245}, + {strProp: 'zeta', numProp: 4358}, + ], + ], + }, + ), + WithSet, + ); + + expect(result).toBeInstanceOf(WithSet); + expect(result.prop).toBeDefined(); + expect(result.prop).toBeInstanceOf(Set); + expect(result.prop.size).toBe(2); + expect(result.getSetSize()).toBe(2); + expect(Array.from(result.prop)).toEqual([ + [ + new Simple({strProp: 'delta', numProp: 4}), + new Simple({strProp: 'bravo', numProp: 2}), + new Simple({strProp: 'gamma', numProp: 0}), + ], + [ + new Simple({strProp: 'alpha', numProp: 3245}), + new Simple({strProp: 'zeta', numProp: 4358}), + ], + ]); + }); + + it('serializes', () => { + const object = new WithSet(); + object.prop = new Set>([ + [new Simple({strProp: 'delta', numProp: 4})], + [ + new Simple({strProp: 'alpha', numProp: 3245}), + new Simple({strProp: 'zeta', numProp: 4358}), + ], + ]); + const result = TypedJSON.stringify(object, WithSet); + + expect(result).toBe(JSON.stringify({ + prop: [ + [ + { + strProp: 'delta', + numProp: 4, + }, + ], + [ + { + strProp: 'alpha', + numProp: 3245, + }, + { + strProp: 'zeta', + numProp: 4358, + }, + ], + ], + })); + }); +}); + +describe('set of raw objects', () => { @jsonObject class WithRawSet { @jsonSetMember(Object) @@ -105,22 +209,22 @@ describe('set of raw objects', function () { function rawObjects() { return [ { - "prop": "something", + prop: 'something', }, { - "another": "value", + another: 'value', }, ]; } - it('should deserialize as is', function () { - const withRawSet = TypedJSON.parse({"rawSet": rawObjects()}, WithRawSet); + it('should deserialize as is', () => { + const withRawSet = TypedJSON.parse({rawSet: rawObjects()}, WithRawSet); expect(withRawSet).toBeDefined(); expect(withRawSet instanceof WithRawSet).toBeTruthy(); expect(withRawSet.rawSet).toEqual(new Set(rawObjects())); }); - it('should serialize as is', function () { + it('should serialize as is', () => { const withRawSet = new WithRawSet(); withRawSet.rawSet = new Set(rawObjects()); const json = TypedJSON.toPlainJson(withRawSet, WithRawSet); diff --git a/spec/to-json.spec.ts b/spec/to-json.spec.ts index 6800add..8a3f829 100644 --- a/spec/to-json.spec.ts +++ b/spec/to-json.spec.ts @@ -1,7 +1,7 @@ -import {jsonObject, jsonMember, toJson} from "../src/typedjson"; +import {jsonMember, jsonObject, toJson} from '../src'; -describe('toJson decorator', function () { - it('should work with JSON.stringify', function () { +describe('toJson decorator', () => { + it('should work with JSON.stringify', () => { @toJson @jsonObject class Person { @@ -10,18 +10,18 @@ describe('toJson decorator', function () { @jsonMember({name: 'surname'}) lastName?: string; - public getFullName() { - return this.firstName + " " + this.lastName; + getFullName() { + return `${this.firstName} ${this.lastName}`; } } - const person = new Person; + const person = new Person(); person.firstName = 'John'; person.lastName = 'Doe'; expect(JSON.stringify(person)).toBe('{"surname":"Doe"}'); }); - it('should work on the abstract class', function () { + it('should work on the abstract class', () => { @toJson abstract class Base { @jsonMember({name: 'renamed'}) @@ -41,20 +41,19 @@ describe('toJson decorator', function () { ignored?: string; } - - const sub = new Sub; + const sub = new Sub(); sub.prop = 'value'; sub.num = 20; expect(JSON.stringify(sub)).toBe('{"renamed":"value","numeric":20}'); - const otherSub = new OtherSub; + const otherSub = new OtherSub(); otherSub.prop = 'value'; otherSub.decimal = 123; otherSub.ignored = 'assigned'; expect(JSON.stringify(otherSub)).toBe('{"renamed":"value","decimal":123}'); }); - it("should throw an error when toJSON already exists", function () { + it('should throw an error when toJSON already exists', () => { try { @toJson @jsonObject @@ -67,7 +66,7 @@ describe('toJson decorator', function () { } } - const some = new Some; + const some = new Some(); some.prop = 'value'; expect(JSON.stringify(some)).toBe('{}'); @@ -77,8 +76,7 @@ describe('toJson decorator', function () { } }); - - it("should overwrite toJSON when overwrite is true", function () { + it('should overwrite toJSON when overwrite is true', () => { @toJson({overwrite: true}) @jsonObject class Some { @@ -90,7 +88,7 @@ describe('toJson decorator', function () { } } - const some = new Some; + const some = new Some(); some.prop = 'value'; expect(JSON.stringify(some)).toBe('{"prop":"value"}'); }); diff --git a/spec/utils/everything.ts b/spec/utils/everything.ts index 637a831..5952cd4 100644 --- a/spec/utils/everything.ts +++ b/spec/utils/everything.ts @@ -1,4 +1,4 @@ -import { jsonObject, jsonMember } from "../../src/typedjson"; +import {jsonMember, jsonObject} from '../../src'; export enum JustEnum { One, @@ -46,7 +46,7 @@ export interface IEverything { // nullable is not supported, use optional instead // nullable: {}|null; optional?: {}; - undefinable: {}|undefined; + undefinable: {} | undefined; enum: JustEnum; constEnum: ConstEnum; strEnum: StrEnum; @@ -64,33 +64,6 @@ export interface IEverything { @jsonObject export class Everything implements IEverything { - static create(): IEverything { - return { - strProp: 'string', - numProp: 123, - boolProp: true, - dateProp: new Date(1543912019), - // nullable: null, - undefinable: undefined, - enum: JustEnum.Four, - constEnum: ConstEnum.Four, - strEnum: StrEnum.Four, - constStrEnum: ConstStrEnum.Four, - // heteroEnum: HeteroEnum.Two, - // heteroEnum2: HeteroEnum.Four, - // constHeteroEnum: ConstHeteroEnum.Two, - // constHeteroEnum2: ConstHeteroEnum.Four, - // [symbolProp]: 'symbol string', - }; - } - - static expected(): Everything { - const obj = Everything.create(); - // properties that are undefined are not serialized - delete obj.undefinable; - return new Everything(obj); - } - @jsonMember strProp: string; @jsonMember @@ -104,7 +77,7 @@ export class Everything implements IEverything { @jsonMember optional?: {}; @jsonMember - undefinable: {}|undefined; + undefinable: {} | undefined; @jsonMember enum: JustEnum; @jsonMember @@ -124,14 +97,39 @@ export class Everything implements IEverything { // @jsonMember // [symbolProp]: string; - constructor(); - constructor(init: IEverything); constructor(init?: IEverything) { - if (init) { + if (init !== undefined) { Object.assign(this, init); } } + static create(): IEverything { + return { + strProp: 'string', + numProp: 123, + boolProp: true, + dateProp: new Date(1543912019), + // nullable: null, + undefinable: undefined, + enum: JustEnum.Four, + constEnum: ConstEnum.Four, + strEnum: StrEnum.Four, + constStrEnum: ConstStrEnum.Four, + // heteroEnum: HeteroEnum.Two, + // heteroEnum2: HeteroEnum.Four, + // constHeteroEnum: ConstHeteroEnum.Two, + // constHeteroEnum2: ConstHeteroEnum.Four, + // [symbolProp]: 'symbol string', + }; + } + + static expected(): Everything { + const obj = Everything.create(); + // properties that are undefined are not serialized + delete obj.undefinable; + return new Everything(obj); + } + foo() { return 'Just to be sure'; } diff --git a/spec/utils/object-compare.ts b/spec/utils/object-compare.ts index 6d6dbf2..3c3d88d 100644 --- a/spec/utils/object-compare.ts +++ b/spec/utils/object-compare.ts @@ -1,47 +1,49 @@ -export function isEqual(a: Object, b: Object): boolean; +export function isEqual(a: Object, b: Object): boolean; export function isEqual(a: T, b: T): boolean; -export function isEqual(a: Array < T >, b: Array): boolean; +export function isEqual(a: Array, b: Array): boolean; export function isEqual(a: any, b: any): boolean { - if (typeof a === "object") { - if (Object.keys(a).length !== Object.keys(b).length) { - // 'b' has a different number of properties, and thus can no longer be considered equal. - console.warn(`Property count mismatch (a: ${Object.keys(a).length} keys, b: ${Object.keys(b).length} keys) on:`); - console.warn(a); - console.warn(b); - return false; - } else { + if (typeof a === 'object') { + if (Object.keys(a).length === Object.keys(b).length) { // Alphabetical iteration over object property keys. return Object.keys(a).sort().reduce((acc, k) => { - if (typeof a[k] === "function" && typeof b[k] === "function") { + if (typeof a[k] === 'function' && typeof b[k] === 'function') { return true; } else { return acc && isEqual(a[k], b[k]); } }, true); - } - } else if (a instanceof Array && b instanceof Array) { - if (a.length !== b.length) { - // 'b' has a different number of elements, not equal. - console.warn(`Array length mismatch (a: ${a.length} elements, b: ${b.length} elements) on:`); + } else { + // 'b' has a different number of properties, and thus can no longer be considered equal. + console.warn( + `Property count mismatch (a: ${Object.keys(a).length} keys,` + + ` b: ${Object.keys(b).length} keys) on:`, + ); console.warn(a); console.warn(b); return false; - } else { + } + } else if (a instanceof Array && b instanceof Array) { + if (a.length === b.length) { // Compare all Array elements recursively. - for (var i = 0; i < a.length; i++) { + for (let i = 0; i < a.length; i++) { if (!isEqual(a[i], b[i])) { // Array elements not equal. return false; } } - } - } else { - if (a !== b) { - console.warn(`Value mismatch (a: '${a}', b: '${b}').`); - return false; } else { - return true; + // 'b' has a different number of elements, not equal. + console.warn( + `Array length mismatch (a: ${a.length} elements, b: ${b.length} elements) on:`, + ); + console.warn(a); + console.warn(b); + return false; } + } else if (a === b) { + return true; } + + console.warn(`Value mismatch (a: '${a}', b: '${b}').`); return false; } diff --git a/src/deserializer.ts b/src/deserializer.ts new file mode 100644 index 0000000..68d6000 --- /dev/null +++ b/src/deserializer.ts @@ -0,0 +1,742 @@ +import {identity, isSubtypeOf, isValueDefined, logError, nameof} from './helpers'; +import {JsonObjectMetadata, TypeResolver} from './metadata'; +import {getOptionValue, mergeOptions, OptionsBase} from './options-base'; +import { + AnyT, + ArrayTypeDescriptor, + ConcreteTypeDescriptor, + ensureTypeDescriptor, + MapShape, + MapTypeDescriptor, + SetTypeDescriptor, + TypeDescriptor, +} from './type-descriptor'; +import {Constructor, IndexedObject, Serializable} from './types'; + +export function defaultTypeResolver( + sourceObject: IndexedObject, + knownTypes: Map, +): Function | undefined { + if (sourceObject.__type != null) { + return knownTypes.get(sourceObject.__type); + } +} + +export type DeserializerFn = ( + sourceObject: Raw, + typeDescriptor: TypeDescriptor, + knownTypes: Map, + memberName: string, + deserializer: Deserializer, + memberOptions?: OptionsBase, +) => T; + +/** + * Utility class, converts a simple/untyped javascript object-tree to a typed object-tree. + * It is used after parsing a JSON-string. + */ +export class Deserializer { + options?: OptionsBase; + + private typeResolver: TypeResolver = defaultTypeResolver; + private nameResolver?: (ctor: Function) => string; + private errorHandler: (error: Error) => void = logError; + private deserializationStrategy = new Map< + Serializable, + DeserializerFn + >([ + // primitives + [AnyT.ctor, identity], + [Number, deserializeDirectly], + [String, deserializeDirectly], + [Boolean, deserializeDirectly], + + [Date, deserializeDate], + [ArrayBuffer, stringToArrayBuffer], + [DataView, stringToDataView], + + [Array, convertAsArray], + [Set, convertAsSet], + [Map, convertAsMap], + + // typed arrays + [Float32Array, convertAsFloatArray], + [Float64Array, convertAsFloatArray], + [Uint8Array, convertAsUintArray], + [Uint8ClampedArray, convertAsUintArray], + [Uint16Array, convertAsUintArray], + [Uint32Array, convertAsUintArray], + ]); + + setDeserializationStrategy( + type: Serializable, + deserializer: DeserializerFn, + ) { + this.deserializationStrategy.set(type, deserializer); + } + + setNameResolver(nameResolverCallback: (ctor: Function) => string) { + this.nameResolver = nameResolverCallback; + } + + setTypeResolver(typeResolverCallback: TypeResolver) { + if (typeof typeResolverCallback as any !== 'function') { + throw new TypeError('\'typeResolverCallback\' is not a function.'); + } + + this.typeResolver = typeResolverCallback; + } + + getTypeResolver(): TypeResolver { + return this.typeResolver; + } + + setErrorHandler(errorHandlerCallback: (error: Error) => void) { + if (typeof errorHandlerCallback as any !== 'function') { + throw new TypeError('\'errorHandlerCallback\' is not a function.'); + } + + this.errorHandler = errorHandlerCallback; + } + + getErrorHandler(): (error: Error) => void { + return this.errorHandler; + } + + convertSingleValue( + sourceObject: any, + typeDescriptor: TypeDescriptor, + knownTypes: Map, + memberName = 'object', + memberOptions?: OptionsBase, + ): any { + if (this.retrievePreserveNull(memberOptions) && sourceObject === null) { + return null; + } else if (!isValueDefined(sourceObject)) { + return; + } + + const deserializer = this.deserializationStrategy.get(typeDescriptor.ctor); + if (deserializer !== undefined) { + return deserializer( + sourceObject, + typeDescriptor, + knownTypes, + memberName, + this, + memberOptions, + ); + } + + if (typeof sourceObject === 'object') { + return convertAsObject(sourceObject, typeDescriptor, knownTypes, memberName, this); + } + + let error = `Could not deserialize '${memberName}'; don't know how to deserialize type`; + + if (typeDescriptor.hasFriendlyName()) { + error += ` '${typeDescriptor.ctor.name}'`; + } + + this.errorHandler(new TypeError(`${error}.`)); + } + + instantiateType(ctor: any) { + return new ctor(); + } + + mergeKnownTypes(...knownTypeMaps: Array>) { + const result = new Map(); + + knownTypeMaps.forEach(knownTypes => { + knownTypes.forEach((ctor, name) => { + if (this.nameResolver === undefined) { + result.set(name, ctor); + } else { + result.set(this.nameResolver(ctor), ctor); + } + }); + }); + + return result; + } + + createKnownTypesMap(knowTypes: Set) { + const map = new Map(); + + knowTypes.forEach(ctor => { + if (this.nameResolver === undefined) { + const knownTypeMeta = JsonObjectMetadata.getFromConstructor(ctor); + const customName = knownTypeMeta?.isExplicitlyMarked === true + ? knownTypeMeta.name + : null; + map.set(customName ?? ctor.name, ctor); + } else { + map.set(this.nameResolver(ctor), ctor); + } + }); + + return map; + } + + retrievePreserveNull(memberOptions?: OptionsBase): boolean { + return getOptionValue('preserveNull', mergeOptions(this.options, memberOptions)); + } +} + +function throwTypeMismatchError( + targetType: string, + expectedSourceType: string, + actualSourceType: string, + memberName: string, +): never { + throw new TypeError( + `Could not deserialize ${memberName} as ${targetType}:` + + ` expected ${expectedSourceType}, got ${actualSourceType}.`, + ); +} + +function makeTypeErrorMessage( + expectedType: Function | string, + actualType: Function | string, + memberName: string, +) { + const expectedTypeName = typeof expectedType === 'function' + ? nameof(expectedType) + : expectedType; + const actualTypeName = typeof actualType === 'function' ? nameof(actualType) : actualType; + + return `Could not deserialize ${memberName}: expected '${expectedTypeName}',` + + ` got '${actualTypeName}'.`; +} + +function srcTypeNameForDebug(sourceObject: any) { + return sourceObject == null ? 'undefined' : nameof(sourceObject.constructor); +} + +function deserializeDirectly( + sourceObject: T, + typeDescriptor: TypeDescriptor, + knownTypes: Map, + objectName: string, +): T { + if (sourceObject.constructor !== typeDescriptor.ctor) { + throw new TypeError(makeTypeErrorMessage( + nameof(typeDescriptor.ctor), + sourceObject.constructor, + objectName, + )); + } + return sourceObject; +} + +function convertAsObject( + sourceObject: IndexedObject, + typeDescriptor: ConcreteTypeDescriptor, + knownTypes: Map, + memberName: string, + deserializer: Deserializer, +): IndexedObject | T | undefined { + if (typeof sourceObject as any !== 'object' || sourceObject as any === null) { + deserializer.getErrorHandler()(new TypeError( + `Cannot deserialize ${memberName}: 'sourceObject' must be a defined object.`, + )); + return undefined; + } + + let expectedSelfType = typeDescriptor.ctor; + let sourceObjectMetadata = JsonObjectMetadata.getFromConstructor(expectedSelfType); + let knownTypeConstructors = knownTypes; + let typeResolver = deserializer.getTypeResolver(); + + if (sourceObjectMetadata !== undefined) { + sourceObjectMetadata.processDeferredKnownTypes(); + + // Merge known types received from "above" with known types defined on the current type. + knownTypeConstructors = deserializer.mergeKnownTypes( + knownTypeConstructors, + deserializer.createKnownTypesMap(sourceObjectMetadata.knownTypes), + ); + if (sourceObjectMetadata.typeResolver != null) { + typeResolver = sourceObjectMetadata.typeResolver; + } + } + + // Check if a type-hint is available from the source object. + const typeFromTypeHint = typeResolver(sourceObject, knownTypeConstructors); + + if (typeFromTypeHint != null) { + // Check if type hint is a valid subtype of the expected source type. + if (isSubtypeOf(typeFromTypeHint, expectedSelfType)) { + // Hell yes. + expectedSelfType = typeFromTypeHint; + sourceObjectMetadata = JsonObjectMetadata.getFromConstructor(typeFromTypeHint); + + if (sourceObjectMetadata !== undefined) { + // Also merge new known types from subtype. + knownTypeConstructors = deserializer.mergeKnownTypes( + knownTypeConstructors, + deserializer.createKnownTypesMap(sourceObjectMetadata.knownTypes), + ); + } + } + } + + if (sourceObjectMetadata?.isExplicitlyMarked === true) { + const sourceMetadata = sourceObjectMetadata; + // Strong-typed deserialization available, get to it. + // First deserialize properties into a temporary object. + const sourceObjectWithDeserializedProperties = {} as IndexedObject; + + const classOptions = mergeOptions(deserializer.options, sourceMetadata.options); + + // Deserialize by expected properties. + sourceMetadata.dataMembers.forEach((objMemberMetadata, propKey) => { + const objMemberValue = sourceObject[propKey]; + const objMemberDebugName = `${nameof(sourceMetadata.classType)}.${propKey}`; + const objMemberOptions = mergeOptions(classOptions, objMemberMetadata.options); + + let revivedValue; + if (objMemberMetadata.deserializer != null) { + revivedValue = objMemberMetadata.deserializer( + objMemberValue, + { + fallback: (so, td) => deserializer.convertSingleValue( + so, + ensureTypeDescriptor(td), + knownTypes, + ), + }, + ); + } else if (objMemberMetadata.type == null) { + throw new TypeError( + `Cannot deserialize ${objMemberDebugName} there is` + + ` no constructor nor deserialization function to use.`, + ); + } else { + revivedValue = deserializer.convertSingleValue( + objMemberValue, + objMemberMetadata.type(), + knownTypeConstructors, + objMemberDebugName, + objMemberOptions, + ); + } + + // @todo revivedValue will never be null in RHS of || + if (isValueDefined(revivedValue) + || (deserializer.retrievePreserveNull(objMemberOptions) + && revivedValue as any === null) + ) { + sourceObjectWithDeserializedProperties[objMemberMetadata.key] = revivedValue; + } else if (objMemberMetadata.isRequired === true) { + deserializer.getErrorHandler()(new TypeError( + `Missing required member '${objMemberDebugName}'.`, + )); + } + }); + + // Next, instantiate target object. + let targetObject: IndexedObject; + + if (typeof sourceObjectMetadata.initializerCallback === 'function') { + try { + targetObject = sourceObjectMetadata.initializerCallback( + sourceObjectWithDeserializedProperties, + sourceObject, + ); + + // Check the validity of user-defined initializer callback. + if (targetObject as any == null) { + throw new TypeError( + `Cannot deserialize ${memberName}:` + + ` 'initializer' function returned undefined/null` + + `, but '${nameof(sourceObjectMetadata.classType)}' was expected.`, + ); + } else if (!(targetObject instanceof sourceObjectMetadata.classType)) { + throw new TypeError( + `Cannot deserialize ${memberName}:` + + `'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) { + deserializer.getErrorHandler()(e); + return undefined; + } + } else { + targetObject = deserializer.instantiateType(expectedSelfType); + } + + // Finally, assign deserialized properties to target object. + Object.assign(targetObject, sourceObjectWithDeserializedProperties); + + // Call onDeserialized method (if any). + const methodName = sourceObjectMetadata.onDeserializedMethodName; + if (methodName != null) { + if (typeof (targetObject as any)[methodName] === 'function') { + // check for member first + (targetObject as any)[methodName](); + } else if (typeof (targetObject.constructor as any)[methodName] === 'function') { + // check for static + (targetObject.constructor as any)[methodName](); + } else { + deserializer.getErrorHandler()(new TypeError( + `onDeserialized callback` + + `'${nameof(sourceObjectMetadata.classType)}.${methodName}' is not a method.`, + )); + } + } + + return targetObject; + } else { + // Untyped deserialization into Object instance. + const targetObject = {} as IndexedObject; + + Object.keys(sourceObject).forEach(sourceKey => { + targetObject[sourceKey] = deserializer.convertSingleValue( + sourceObject[sourceKey], + new ConcreteTypeDescriptor(sourceObject[sourceKey].constructor), + knownTypes, + sourceKey, + ); + }); + + return targetObject; + } +} + +function convertAsArray( + sourceObject: any, + typeDescriptor: TypeDescriptor, + knownTypes: Map, + memberName: string, + deserializer: Deserializer, + memberOptions?: OptionsBase, +): Array { + if (!(typeDescriptor instanceof ArrayTypeDescriptor)) { + throw new TypeError( + `Could not deserialize ${memberName} as Array: incorrect TypeDescriptor detected,` + + ' please use proper annotation or function for this type', + ); + } + if (!Array.isArray(sourceObject)) { + deserializer.getErrorHandler()( + new TypeError(makeTypeErrorMessage(Array, sourceObject.constructor, memberName)), + ); + return []; + } + + if (typeDescriptor.elementType as any == null) { + deserializer.getErrorHandler()( + new TypeError( + `Could not deserialize ${memberName} as Array: missing constructor reference of` + + ` Array elements.`, + ), + ); + return []; + } + + return sourceObject.map((element, i) => { + // 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 deserializer.convertSingleValue( + element, + typeDescriptor.elementType, + knownTypes, + `${memberName}[${i}]`, + memberOptions, + ); + } catch (e) { + deserializer.getErrorHandler()(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; + } + }); +} + +function convertAsSet( + sourceObject: any, + typeDescriptor: TypeDescriptor, + knownTypes: Map, + memberName: string, + deserializer: Deserializer, + memberOptions?: OptionsBase, +): Set { + if (!(typeDescriptor instanceof SetTypeDescriptor)) { + throw new TypeError( + `Could not deserialize ${memberName} as Set: incorrect TypeDescriptor detected,` + + ` please use proper annotation or function for this type`, + ); + } + if (!Array.isArray(sourceObject)) { + deserializer.getErrorHandler()(new TypeError(makeTypeErrorMessage( + Array, + sourceObject.constructor, + memberName, + ))); + return new Set(); + } + + if (typeDescriptor.elementType as any == null) { + deserializer.getErrorHandler()( + new TypeError( + `Could not deserialize ${memberName} as Set: missing constructor reference of` + + ` Set elements.`, + ), + ); + return new Set(); + } + + const resultSet = new Set(); + + sourceObject.forEach((element, i) => { + try { + resultSet.add(deserializer.convertSingleValue( + element, + typeDescriptor.elementType, + knownTypes, + `${memberName}[${i}]`, + memberOptions, + )); + } catch (e) { + // Faulty entries are skipped, because a Set is not ordered, and skipping an entry + // does not affect others. + deserializer.getErrorHandler()(e); + } + }); + + return resultSet; +} + +function isExpectedMapShape(source: any, expectedShape: MapShape): boolean { + return (expectedShape === MapShape.ARRAY && Array.isArray(source)) + || (expectedShape === MapShape.OBJECT && typeof source === 'object'); +} + +function convertAsMap( + sourceObject: any, + typeDescriptor: TypeDescriptor, + knownTypes: Map, + memberName: string, + deserializer: Deserializer, + memberOptions?: OptionsBase, +): Map { + if (!(typeDescriptor instanceof MapTypeDescriptor)) { + throw new TypeError( + `Could not deserialize ${memberName} as Map: incorrect TypeDescriptor detected,` + + 'please use proper annotation or function for this type', + ); + } + const expectedShape = typeDescriptor.getCompleteOptions().shape; + if (!isExpectedMapShape(sourceObject, expectedShape)) { + const expectedType = expectedShape === MapShape.ARRAY ? Array : Object; + deserializer.getErrorHandler()( + new TypeError(makeTypeErrorMessage(expectedType, sourceObject.constructor, memberName)), + ); + return new Map(); + } + + if (typeDescriptor.keyType as any == null) { + deserializer.getErrorHandler()( + new TypeError(`Could not deserialize ${memberName} as Map: missing key constructor.`), + ); + return new Map(); + } + + if (typeDescriptor.valueType as any == null) { + deserializer.getErrorHandler()( + new TypeError(`Could not deserialize ${memberName} as Map: missing value constructor.`), + ); + return new Map(); + } + + const keyMemberName = `${memberName}[].key`; + const valueMemberName = `${memberName}[].value`; + const resultMap = new Map(); + + if (expectedShape === MapShape.OBJECT) { + Object.keys(sourceObject).forEach(key => { + try { + const resultKey = deserializer.convertSingleValue( + key, + typeDescriptor.keyType, + knownTypes, + keyMemberName, + memberOptions, + ); + if (isValueDefined(resultKey)) { + resultMap.set( + resultKey, + deserializer.convertSingleValue( + sourceObject[key], + typeDescriptor.valueType, + knownTypes, + valueMemberName, + memberOptions, + ), + ); + } + } catch (e) { + // Faulty entries are skipped, because a Map is not ordered, + // and skipping an entry does not affect others. + deserializer.getErrorHandler()(e); + } + }); + } else { + sourceObject.forEach((element: any) => { + try { + const key = deserializer.convertSingleValue( + element.key, + typeDescriptor.keyType, + knownTypes, + keyMemberName, + memberOptions, + ); + + // Undefined/null keys not supported, skip if so. + if (isValueDefined(key)) { + resultMap.set( + key, + deserializer.convertSingleValue( + element.value, + typeDescriptor.valueType, + knownTypes, + valueMemberName, + memberOptions, + ), + ); + } + } catch (e) { + // Faulty entries are skipped, because a Map is not ordered, + // and skipping an entry does not affect others. + deserializer.getErrorHandler()(e); + } + }); + } + + return resultMap; +} + +function deserializeDate( + sourceObject: string | number | Date, + typeDescriptor: TypeDescriptor, + knownTypes: Map, + memberName: string, +): 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 === 'number') { + const isInteger = sourceObject % 1 === 0; + if (!isInteger) { + throw new TypeError( + `Could not deserialize ${memberName} as Date:` + + ` expected an integer, got a number with decimal places.`, + ); + } + + return new Date(sourceObject); + } else if (typeof sourceObject === 'string') { + return new Date(sourceObject); + } else if (sourceObject instanceof Date) { + return sourceObject; + } else { + throwTypeMismatchError( + 'Date', + 'an ISO-8601 string', + srcTypeNameForDebug(sourceObject), + memberName, + ); + } +} + +function stringToArrayBuffer( + sourceObject: string | number | Date, + typeDescriptor: TypeDescriptor, + knownTypes: Map, + memberName: string, +) { + if (typeof sourceObject !== 'string') { + throwTypeMismatchError( + 'ArrayBuffer', + 'a string source', + srcTypeNameForDebug(sourceObject), + memberName, + ); + } + return createArrayBufferFromString(sourceObject); +} + +function stringToDataView( + sourceObject: string | number | Date, + typeDescriptor: TypeDescriptor, + knownTypes: Map, + memberName: string, +) { + if (typeof sourceObject !== 'string') { + throwTypeMismatchError( + 'DataView', + 'a string source', + srcTypeNameForDebug(sourceObject), + memberName, + ); + } + return new DataView(createArrayBufferFromString(sourceObject)); +} + +function createArrayBufferFromString(input: string): ArrayBuffer { + const buf = new ArrayBuffer(input.length * 2); // 2 bytes for each char + const bufView = new Uint16Array(buf); + + for (let i = 0, strLen = input.length; i < strLen; i++) { + bufView[i] = input.charCodeAt(i); + } + + return buf; +} + +function convertAsFloatArray( + sourceObject: string | number | Date, + typeDescriptor: TypeDescriptor, + knownTypes: Map, + memberName: string, +): T { + const constructor = typeDescriptor.ctor as Constructor; + if (Array.isArray(sourceObject) && sourceObject.every(elem => !isNaN(elem))) { + return new constructor(sourceObject); + } + return throwTypeMismatchError( + constructor.name, + 'a numeric source array', + srcTypeNameForDebug(sourceObject), + memberName, + ); +} + +// @todo: investigate bitwise and types +function convertAsUintArray( + sourceObject: string | number | Date, + typeDescriptor: TypeDescriptor, + knownTypes: Map, + memberName: string, +): T { + const constructor = typeDescriptor.ctor as Constructor; + if (Array.isArray(sourceObject) && sourceObject.every(elem => !isNaN(elem))) { + // eslint-disable-next-line no-bitwise + return new constructor(sourceObject.map(value => ~~value)); + } + return throwTypeMismatchError( + typeDescriptor.ctor.name, + 'a numeric source array', + srcTypeNameForDebug(sourceObject), + memberName, + ); +} diff --git a/src/helpers.ts b/src/helpers.ts new file mode 100644 index 0000000..fcfb242 --- /dev/null +++ b/src/helpers.ts @@ -0,0 +1,146 @@ +import {AnyT} from './type-descriptor'; +import {Serializable} from './types'; + +declare abstract class Reflect { + static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any; +} + +export const LAZY_TYPE_EXPLANATION = `If the type is not yet defined, for example due to circular \ +references, add '() => ' before it. E.g. @jsonMember(() => Foo)`; + +export const MISSING_REFLECT_CONF_MSG = 'Make sure that you have both "experimentalDecorators"' + + ' and "emitDecoratorMetadata" enabled in your tsconfig.json'; + +/** + * Determines whether the specified type is a type that can be passed on "as-is" into + * `JSON.stringify`. + * Values of these types don't need special conversion. + * @param type The constructor of the type (wrapper constructor for primitive types, e.g. `Number` + * for `number`). + */ +export function isDirectlySerializableNativeType(type: Function): boolean { + return [Date, Number, String, Boolean].indexOf(type as any) !== -1; +} + +export function isDirectlyDeserializableNativeType(type: Function): boolean { + return [Number, String, Boolean].indexOf(type as any) !== -1; +} + +export function isTypeTypedArray(type: Function): boolean { + return [ + Float32Array, + Float64Array, + Int8Array, + Uint8Array, + Uint8ClampedArray, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + ].indexOf(type as any) !== -1; +} + +export function isObject(value: any): value is Object { + return typeof value === 'object'; +} + +export function shouldOmitParseString(jsonStr: string, expectedType: Function): boolean { + const expectsTypesSerializedAsStrings = expectedType === String + || expectedType === ArrayBuffer + || expectedType === DataView; + + const hasQuotes = jsonStr.length >= 2 + && jsonStr[0] === '"' + && jsonStr[jsonStr.length - 1] === '"'; + + if (expectedType === Date) { + // Date can both have strings and numbers as input + const isNumber = !isNaN(Number(jsonStr.trim())); + return !hasQuotes && !isNumber; + } + + return expectsTypesSerializedAsStrings && !hasQuotes; +} + +export function parseToJSObject(json: any, expectedType: Serializable): Object { + if (typeof json !== 'string' || shouldOmitParseString(json, expectedType)) { + return json; + } + return JSON.parse(json); +} + +/** + * Determines if 'A' is a sub-type of 'B' (or if 'A' equals 'B'). + * @param A The supposed derived type. + * @param B The supposed base type. + */ +export function isSubtypeOf(A: Function, B: Function) { + return A === B || A.prototype instanceof B; +} + +export function logError(message?: any, ...optionalParams: Array) { + if (typeof console as any === 'object' && typeof console.error as any === 'function') { + console.error(message, ...optionalParams); + } else if (typeof console as any === 'object' && typeof console.log as any === 'function') { + console.log(`ERROR: ${message}`, ...optionalParams); + } +} + +export function logMessage(message?: any, ...optionalParams: Array) { + if (typeof console as any === 'object' && typeof console.log as any === 'function') { + console.log(message, ...optionalParams); + } +} + +export function logWarning(message?: any, ...optionalParams: Array) { + if (typeof console as any === 'object' && typeof console.warn as any === 'function') { + console.warn(message, ...optionalParams); + } else if (typeof console as any === 'object' && typeof console.log as any === 'function') { + console.log(`WARNING: ${message}`, ...optionalParams); + } +} + +export type NotNull = T extends null ? never : T; +export type RequiredNoNull = {[P in keyof T]-?: NotNull}; + +/** + * Checks if the value is considered defined (not undefined and not null). + * @param value + */ +export function isValueDefined(value: T): value is Exclude { + return !(typeof value === 'undefined' || value === null); +} + +export function isInstanceOf(value: any, constructor: Function): boolean { + if (constructor === AnyT.ctor) { + return true; + } else if (typeof value === 'number') { + return constructor === Number; + } else if (typeof value === 'string') { + return constructor === String; + } else if (typeof value === 'boolean') { + return constructor === Boolean; + } else if (isObject(value)) { + return value instanceof constructor; + } + + return false; +} + +export const isReflectMetadataSupported = + typeof Reflect as any === 'object' && typeof Reflect.getMetadata as any === 'function'; + +/** + * Gets the name of a function. + * @param fn The function whose name to get. + */ +export function nameof(fn: Function & {name?: string}) { + if (typeof fn.name as string | undefined === 'string') { + return fn.name; + } + return 'undefined'; +} + +export function identity(arg: T): T { + return arg; +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..6899a55 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,33 @@ +export { + TypedJSON, + ITypedJSONSettings, + JsonTypes, + defaultTypeResolver, + defaultTypeEmitter, +} from './parser'; +export {TypeResolver, TypeHintEmitter, JsonObjectMetadata} from './metadata'; +export { + jsonObject, + IJsonObjectOptions, + InitializerCallback, + IJsonObjectOptionsWithInitializer, + IJsonObjectOptionsBase, +} from './json-object'; +export {jsonMember, IJsonMemberOptions} from './json-member'; +export {jsonArrayMember, IJsonArrayMemberOptions} from './json-array-member'; +export {jsonSetMember, IJsonSetMemberOptions} from './json-set-member'; +export {jsonMapMember, IJsonMapMemberOptions} from './json-map-member'; +export {toJson, IToJsonOptions} from './to-json'; +export { + ArrayT, + AnyT, + SetT, + MapT, + Typelike, + MapOptions, + MapShape, + SetTypeDescriptor, + ArrayTypeDescriptor, + MapTypeDescriptor, +} from './type-descriptor'; +export * from './types'; diff --git a/src/json-array-member.ts b/src/json-array-member.ts new file mode 100644 index 0000000..f70173d --- /dev/null +++ b/src/json-array-member.ts @@ -0,0 +1,98 @@ +import {isReflectMetadataSupported, logError, MISSING_REFLECT_CONF_MSG, nameof} from './helpers'; +import { + CustomDeserializerParams, + CustomSerializerParams, + injectMetadataInformation, +} from './metadata'; +import {extractOptionBase, OptionsBase} from './options-base'; +import { + ArrayTypeDescriptor, + ensureTypeDescriptor, + ensureTypeThunk, + MaybeTypeThunk, + TypeDescriptor, + TypeThunk, +} from './type-descriptor'; + +declare abstract class Reflect { + static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any; +} + +export interface IJsonArrayMemberOptions extends OptionsBase { + /** When set, indicates that the member must be present when deserializing. */ + isRequired?: boolean | null; + + /** When set, an empty array is emitted if the property is undefined/uninitialized. */ + emitDefaultValue?: boolean | null; + + /** Sets array dimensions (e.g. 1 for 'number[]' or 2 for 'number[][]'). Defaults to 1. */ + dimensions?: number | null; + + /** When set, the key on the JSON that should be used instead of the class property name */ + name?: string | null; + + /** + * When set, this deserializer will be used to deserialize the member. The callee must assure + * the correct type. + */ + deserializer?: ((json: any, params: CustomDeserializerParams) => any) | null; + + /** When set, this serializer will be used to serialize the member. */ + serializer?: ((value: any, params: CustomSerializerParams) => any) | null; +} + +/** + * Specifies that a property, of type array, is part of an object when serializing. + * @param maybeTypeThunk Constructor of array elements (e.g. 'Number' for 'number[]', or 'Date' + * for 'Date[]'). + * @param options Additional options. + */ +export function jsonArrayMember( + maybeTypeThunk: MaybeTypeThunk, + options: IJsonArrayMemberOptions = {}, +) { + return (target: Object, propKey: string | symbol) => { + const decoratorName = + `@jsonArrayMember on ${nameof(target.constructor)}.${String(propKey)}`; + const typeThunk: TypeThunk = ensureTypeThunk(maybeTypeThunk, decoratorName); + + const dimensions = options.dimensions == null ? 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. + const reflectedType = isReflectMetadataSupported + ? Reflect.getMetadata('design:type', target, propKey) + : null; + + if (reflectedType != null && reflectedType !== Array && reflectedType !== Object) { + logError(`${decoratorName}: property is not an Array. ${MISSING_REFLECT_CONF_MSG}`); + return; + } + + injectMetadataInformation(target, propKey, { + type: () => createArrayType(ensureTypeDescriptor(typeThunk()), dimensions), + emitDefaultValue: options.emitDefaultValue, + isRequired: options.isRequired, + options: extractOptionBase(options), + key: propKey.toString(), + name: options.name ?? propKey.toString(), + deserializer: options.deserializer, + serializer: options.serializer, + }); + }; +} + +export function createArrayType( + elementType: TypeDescriptor, + dimensions: number, +): ArrayTypeDescriptor { + let type = new ArrayTypeDescriptor(elementType); + for (let i = 1; i < dimensions; ++i) { + type = new ArrayTypeDescriptor(type); + } + return type; +} diff --git a/src/json-map-member.ts b/src/json-map-member.ts new file mode 100644 index 0000000..ec20658 --- /dev/null +++ b/src/json-map-member.ts @@ -0,0 +1,74 @@ +import {isReflectMetadataSupported, logError, MISSING_REFLECT_CONF_MSG, nameof} from './helpers'; +import { + CustomDeserializerParams, + CustomSerializerParams, + injectMetadataInformation, +} from './metadata'; +import {extractOptionBase, OptionsBase} from './options-base'; +import {ensureTypeThunk, MapOptions, MapT, MaybeTypeThunk} from './type-descriptor'; + +declare abstract class Reflect { + static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any; +} + +export interface IJsonMapMemberOptions extends OptionsBase, Partial { + /** When set, indicates that the member must be present when deserializing. */ + isRequired?: boolean | null; + + /** When set, a default value is emitted for each uninitialized json member. */ + emitDefaultValue?: boolean | null; + + /** When set, the key on the JSON that should be used instead of the class property name */ + name?: string | null; + + /** + * When set, this deserializer will be used to deserialize the member. The callee must assure + * the correct type. + */ + deserializer?: ((json: any, params: CustomDeserializerParams) => any) | null; + + /** When set, this serializer will be used to serialize the member. */ + serializer?: ((value: any, params: CustomSerializerParams) => any) | null; +} + +/** + * Specifies that the property is part of the object when serializing. + * Use this decorator on properties of type Map. + * @param maybeKeyThunk Constructor of map keys (e.g. 'Number' for 'Map'). + * @param maybeValueThunk Constructor of map values (e.g. 'Date' for 'Map'). + * @param options Additional options. + */ +export function jsonMapMember( + maybeKeyThunk: MaybeTypeThunk, + maybeValueThunk: MaybeTypeThunk, + options: IJsonMapMemberOptions = {}, +) { + return (target: Object, propKey: string | symbol) => { + // For error messages + const decoratorName = `@jsonMapMember on ${nameof(target.constructor)}.${String(propKey)}`; + const keyThunk = ensureTypeThunk(maybeKeyThunk, decoratorName); + const valueThunk = ensureTypeThunk(maybeValueThunk, decoratorName); + + // If ReflectDecorators is available, use it to check whether 'jsonMapMember' has been used + // on a map. Warn if not. + const reflectedType = isReflectMetadataSupported + ? Reflect.getMetadata('design:type', target, propKey) + : null; + + if (reflectedType != null && reflectedType !== Map && reflectedType !== Object) { + logError(`${decoratorName}: property is not a Map. ${MISSING_REFLECT_CONF_MSG}`); + return; + } + + injectMetadataInformation(target, propKey, { + type: () => MapT(keyThunk(), valueThunk(), {shape: options.shape}), + emitDefaultValue: options.emitDefaultValue, + isRequired: options.isRequired, + options: extractOptionBase(options), + key: propKey.toString(), + name: options.name ?? propKey.toString(), + deserializer: options.deserializer, + serializer: options.serializer, + }); + }; +} diff --git a/src/json-member.ts b/src/json-member.ts new file mode 100644 index 0000000..52d8b82 --- /dev/null +++ b/src/json-member.ts @@ -0,0 +1,241 @@ +import { + isReflectMetadataSupported, + isSubtypeOf, + isValueDefined, + LAZY_TYPE_EXPLANATION, + logError, + logWarning, + MISSING_REFLECT_CONF_MSG, + nameof, +} from './helpers'; +import { + CustomDeserializerParams, + CustomSerializerParams, + injectMetadataInformation, +} from './metadata'; +import {extractOptionBase, OptionsBase} from './options-base'; +import { + ArrayTypeDescriptor, + ensureTypeDescriptor, + ensureTypeThunk, + isTypelike, + isTypeThunk, + MapTypeDescriptor, + MaybeTypeThunk, + SetTypeDescriptor, + TypeDescriptor, + Typelike, + TypeThunk, +} from './type-descriptor'; +import {Constructor, IndexedObject} from './types'; + +declare abstract class Reflect { + static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any; +} + +export interface IJsonMemberOptions extends OptionsBase { + /** + * Sets the constructor of the property. + * Optional with ReflectDecorators. + */ + constructor?: Typelike | null; + + /** When set, indicates that the member must be present when deserializing. */ + isRequired?: boolean | null; + + /** When set, a default value is emitted if the property is uninitialized/undefined. */ + emitDefaultValue?: boolean | null; + + /** When set, the key on the JSON that should be used instead of the class property name. */ + name?: string | null; + + /** + * When set, this deserializer will be used to deserialize the member. The callee must assure + * the correct type. + */ + deserializer?: ((json: any, params: CustomDeserializerParams) => any) | null; + + /** When set, this serializer will be used to serialize the member. */ + serializer?: ((value: any, params: CustomSerializerParams) => any) | null; +} + +/** + * Specifies that a property is part of the object when serializing. + * Requires ReflectDecorators. + */ +export function jsonMember( + prototype: IndexedObject, + propertyKey: string | symbol, +): void; + +/** + * Specifies that a property is part of the object when serializing, with additional options. + * Requires ReflectDecorators. + */ +export function jsonMember(options: IJsonMemberOptions): PropertyDecorator; + +/** + * Specifies that a property is part of the object when serializing, with a defined type and extra + * options. + */ +export function jsonMember( + type: MaybeTypeThunk, + options?: IJsonMemberOptions, +): PropertyDecorator; + +export function jsonMember( + optionsOrPrototype?: IndexedObject | IJsonMemberOptions | MaybeTypeThunk, + propertyKeyOrOptions?: string | symbol | IJsonMemberOptions, +): PropertyDecorator | void { + if (typeof propertyKeyOrOptions === 'string' || typeof propertyKeyOrOptions === 'symbol') { + const property = propertyKeyOrOptions as string; + const prototype = optionsOrPrototype as IndexedObject; + // For error messages. + const decoratorName = `@jsonMember on ${nameof(prototype.constructor)}.${String(property)}`; + + // jsonMember used directly, no additional information directly available besides target and + // propKey. + // Obtain property constructor through ReflectDecorators. + if (!isReflectMetadataSupported) { + logError(`${decoratorName}: ReflectDecorators is required if the type is not \ +explicitly provided with e.g. @jsonMember(Number)`); + return; + } + + const reflectPropCtor: Function | null | undefined = + Reflect.getMetadata('design:type', prototype, property); + + if (reflectPropCtor == null) { + logError(`${decoratorName}: could not resolve detected property constructor at \ +runtime. Potential solutions: + - ${LAZY_TYPE_EXPLANATION} + - ${MISSING_REFLECT_CONF_MSG}`); + return; + } + + const typeDescriptor = ensureTypeDescriptor(reflectPropCtor); + if (isSpecialPropertyType(decoratorName, typeDescriptor)) { + return; + } + + injectMetadataInformation(prototype, property, { + type: () => typeDescriptor, + key: propertyKeyOrOptions.toString(), + name: propertyKeyOrOptions.toString(), + }); + return; + } + + // jsonMember used as a decorator factory. + return jsonMemberDecoratorFactory(optionsOrPrototype, propertyKeyOrOptions); +} + +function jsonMemberDecoratorFactory( + optionsOrType: IJsonMemberOptions | MaybeTypeThunk | undefined, + options: IJsonMemberOptions | undefined, +): PropertyDecorator { + return (target, property) => { + const decoratorName = `@jsonMember on ${nameof(target.constructor)}.${String(property)}`; + let typeThunk: TypeThunk | undefined; + + if (isTypelike(optionsOrType) || isTypeThunk(optionsOrType)) { + typeThunk = ensureTypeThunk(optionsOrType, decoratorName); + } else { + options = optionsOrType; + } + + options = options ?? {}; + + if (Object.prototype.hasOwnProperty.call(options, 'constructor')) { + if (typeThunk !== undefined) { + throw new Error( + 'Cannot both define constructor option and type. Only one allowed.', + ); + } + + if (!isValueDefined(options.constructor)) { + logError(`${decoratorName}: cannot resolve specified property constructor at \ +runtime. ${LAZY_TYPE_EXPLANATION}`); + return; + } + + // Property constructor has been specified. Use ReflectDecorators (if available) to + // check whether that constructor is correct. Warn if not. + const newTypeDescriptor = ensureTypeDescriptor(options.constructor); + typeThunk = () => newTypeDescriptor; + if (isReflectMetadataSupported && !isSubtypeOf( + newTypeDescriptor.ctor, + Reflect.getMetadata('design:type', target, property), + )) { + logWarning( + `${decoratorName}: detected property type does not match` + + ` 'constructor' option.`, + ); + } + } else if (typeThunk !== undefined) { + // Do nothing + } else if (isReflectMetadataSupported) { + const reflectCtor = Reflect.getMetadata( + 'design:type', + target, + property, + ) as Function | null | undefined; + + if (reflectCtor == null) { + logError(`${decoratorName}: cannot resolve detected property constructor at \ +runtime. ${LAZY_TYPE_EXPLANATION}`); + return; + } + typeThunk = () => ensureTypeDescriptor(reflectCtor); + } else if (options.deserializer === undefined) { + logError(`${decoratorName}: Cannot determine type`); + return; + } + + const typeToTest = typeThunk?.(); + + if (typeToTest !== undefined && isSpecialPropertyType(decoratorName, typeToTest)) { + return; + } + + injectMetadataInformation(target, property, { + type: typeThunk === undefined + ? undefined + : () => ensureTypeDescriptor(typeThunk!()), + emitDefaultValue: options.emitDefaultValue, + isRequired: options.isRequired, + options: extractOptionBase(options), + key: property.toString(), + name: options.name ?? property.toString(), + deserializer: options.deserializer, + serializer: options.serializer, + }); + }; +} + +function isConstructorEqual(type: Typelike, constructor: Constructor) { + return type instanceof TypeDescriptor ? type.ctor === constructor : type === constructor; +} + +function isSpecialPropertyType(decoratorName: string, typeDescriptor: Typelike) { + if (!(typeDescriptor instanceof ArrayTypeDescriptor) + && isConstructorEqual(typeDescriptor, Array)) { + logError(`${decoratorName}: property is an Array. Use the jsonArrayMember decorator to` + + ` serialize this property.`); + return true; + } + + if (!(typeDescriptor instanceof SetTypeDescriptor) && isConstructorEqual(typeDescriptor, Set)) { + logError(`${decoratorName}: property is a Set. Use the jsonSetMember decorator to` + + ` serialize this property.`); + return true; + } + + if (!(typeDescriptor instanceof MapTypeDescriptor) && isConstructorEqual(typeDescriptor, Map)) { + logError(`${decoratorName}: property is a Map. Use the jsonMapMember decorator to` + + ` serialize this property.`); + return true; + } + + return false; +} diff --git a/src/typedjson/json-object.ts b/src/json-object.ts similarity index 51% rename from src/typedjson/json-object.ts rename to src/json-object.ts index 2ffa41c..5aad869 100644 --- a/src/typedjson/json-object.ts +++ b/src/json-object.ts @@ -1,38 +1,46 @@ -import { Constructor, ParameterlessConstructor } from "./types"; -import { METADATA_FIELD_KEY } from "./helpers"; -import { JsonObjectMetadata } from "./metadata"; -import { extractOptionBase, OptionsBase } from "./options-base"; +import {JsonObjectMetadata, TypeHintEmitter, TypeResolver} from './metadata'; +import {extractOptionBase, OptionsBase} from './options-base'; +import {Serializable} from './types'; export type InitializerCallback = (sourceObject: T, rawSourceObject: T) => T; -export interface IJsonObjectOptionsBase extends OptionsBase -{ +export interface IJsonObjectOptionsBase extends OptionsBase { /** - * An array of known types to recognize when encountering type-hints, - * or the name of a static method used for determining known types. + * An array of known types to recognize when encountering type-hints. */ - knownTypes?: Function[] | string; + knownTypes?: Array | null; + + /** + * A function that will emit a type hint on the resulting JSON. It will override the global + * typeEmitter. + */ + typeHintEmitter?: TypeHintEmitter | null; + + /** + * A function that given a source object will resolve the type that should be instantiated. + * It will override the global type resolver. + */ + typeResolver?: TypeResolver | null; /** * The name of a static or instance method to call when deserialization * of the object is completed. */ - onDeserialized?: string; + onDeserialized?: string | null; /** * The name of a static or instance method to call before the serialization * of the typed object is started. */ - beforeSerialization?: string; + beforeSerialization?: string | null; /** * The name used to differentiate between different polymorphic types. */ - name?: string; + name?: string | null; } -export interface IJsonObjectOptionsWithInitializer extends IJsonObjectOptionsBase -{ +export interface IJsonObjectOptionsWithInitializer extends IJsonObjectOptionsBase { /** * Function to call before deserializing and initializing the object, accepting two arguments: * (1) sourceObject, an 'Object' instance with all properties already deserialized, and @@ -42,123 +50,89 @@ export interface IJsonObjectOptionsWithInitializer extends IJsonObjectOptions initializer: InitializerCallback; } -export interface IJsonObjectOptions extends IJsonObjectOptionsBase -{ +export interface IJsonObjectOptions extends IJsonObjectOptionsBase { /** * Function to call before deserializing and initializing the object, accepting two arguments: * (1) sourceObject, an 'Object' instance with all properties already deserialized, and * (2) rawSourceObject, a raw 'Object' instance representation of the current object in * the serialized JSON (i.e. without deserialized properties). */ - initializer?: InitializerCallback; + initializer?: InitializerCallback | null; } /** - * Marks that a class with a parameterized constructor is serializable using TypedJSON, with additional - * settings. The 'initializer' setting must be specified. + * Marks that a class with a parameterized constructor is serializable using TypedJSON, with + * additional settings. The 'initializer' setting must be specified. * @param options Configuration settings. */ -export function jsonObject(options?: IJsonObjectOptionsWithInitializer): (target: Constructor) => void; +export function jsonObject( + options?: IJsonObjectOptionsWithInitializer, +): (target: Serializable) => void; /** * Marks that a class is serializable using TypedJSON, with additional settings. * @param options Configuration settings. */ -export function jsonObject(options?: IJsonObjectOptions): (target: ParameterlessConstructor) => void; +// eslint-disable-next-line @typescript-eslint/unified-signatures +export function jsonObject(options?: IJsonObjectOptions): (target: Serializable) => void; /** * Marks that a class with a parameterless constructor is serializable using TypedJSON. */ -export function jsonObject(target: ParameterlessConstructor): void; +export function jsonObject(target: Serializable): void; -export function jsonObject(optionsOrTarget?: IJsonObjectOptions | Constructor -): ((target: Constructor) => void) | void { +export function jsonObject( + optionsOrTarget?: IJsonObjectOptions | Serializable, +): ((target: Serializable) => void) | void { let options: IJsonObjectOptions; - if (typeof optionsOrTarget === "function") - { + if (typeof optionsOrTarget === 'function') { // jsonObject is being used as a decorator, directly. options = {}; - } - else - { + } else { // jsonObject is being used as a decorator factory. - options = optionsOrTarget || {}; + options = optionsOrTarget ?? {}; } function decorator( - target: Function + target: Serializable, ): void { - let objectMetadata: JsonObjectMetadata; - // 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 JsonObjectMetadata(target); - - // Inherit json members and known types from parent @jsonObject (if any). - const parentMetadata: JsonObjectMetadata = target.prototype[METADATA_FIELD_KEY]; - if (parentMetadata) - { - parentMetadata.dataMembers - .forEach((memberMetadata, propKey) => - objectMetadata.dataMembers.set(propKey, memberMetadata)); - parentMetadata.knownTypes - .forEach((knownType) => 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; - } + const objectMetadata = JsonObjectMetadata.ensurePresentInPrototype(target.prototype); // Fill JsonObjectMetadata. objectMetadata.isExplicitlyMarked = true; objectMetadata.onDeserializedMethodName = options.onDeserialized; objectMetadata.beforeSerializationMethodName = options.beforeSerialization; - + + if (options.typeResolver != null) { + objectMetadata.typeResolver = options.typeResolver; + } + if (options.typeHintEmitter != null) { + objectMetadata.typeHintEmitter = options.typeHintEmitter; + } + // T extend Object so it is fine objectMetadata.initializerCallback = options.initializer as any; - if (options.name) - { + if (options.name != null) { objectMetadata.name = options.name; } const optionsBase = extractOptionBase(options); - if (optionsBase) - { + if (optionsBase !== undefined) { objectMetadata.options = optionsBase; } - // Obtain known-types. - if (typeof options.knownTypes === "string") - { - objectMetadata.knownTypeMethodName = options.knownTypes; - } - else if (options.knownTypes instanceof Array) - { + if (options.knownTypes != null) { options.knownTypes - .filter(knownType => !!knownType) + .filter(knownType => Boolean(knownType)) .forEach(knownType => objectMetadata.knownTypes.add(knownType)); } } - if (typeof optionsOrTarget === "function") - { + if (typeof optionsOrTarget === 'function') { // jsonObject is being used as a decorator, directly. decorator(optionsOrTarget); - } - else - { + } else { // jsonObject is being used as a decorator factory. return decorator; } diff --git a/src/json-set-member.ts b/src/json-set-member.ts new file mode 100644 index 0000000..fc4201c --- /dev/null +++ b/src/json-set-member.ts @@ -0,0 +1,69 @@ +import {isReflectMetadataSupported, logError, MISSING_REFLECT_CONF_MSG, nameof} from './helpers'; +import { + CustomDeserializerParams, + CustomSerializerParams, + injectMetadataInformation, +} from './metadata'; +import {extractOptionBase, OptionsBase} from './options-base'; +import {ensureTypeThunk, MaybeTypeThunk, SetT} from './type-descriptor'; + +declare abstract class Reflect { + static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any; +} + +export interface IJsonSetMemberOptions extends OptionsBase { + /** When set, indicates that the member must be present when deserializing. */ + isRequired?: boolean | null; + + /** When set, a default value is emitted for each uninitialized json member. */ + emitDefaultValue?: boolean | null; + + /** When set, the key on the JSON that should be used instead of the class property name */ + name?: string | null; + + /** + * When set, this deserializer will be used to deserialize the member. The callee must assure + * the correct type. + */ + deserializer?: ((json: any, params: CustomDeserializerParams) => any) | null; + + /** When set, this serializer will be used to serialize the member. */ + serializer?: ((value: any, params: CustomSerializerParams) => any) | null; +} + +/** + * Specifies that the property is part of the object when serializing. + * Use this decorator on properties of type Set. + * @param maybeTypeThunk Constructor of set elements (e.g. 'Number' for Set or 'Date' + * for Set). + * @param options Additional options. + */ +export function jsonSetMember(maybeTypeThunk: MaybeTypeThunk, options: IJsonSetMemberOptions = {}) { + return (target: Object, propKey: string | symbol) => { + // For error messages + const decoratorName = `@jsonSetMember on ${nameof(target.constructor)}.${String(propKey)}`; + const typeThunk = ensureTypeThunk(maybeTypeThunk, decoratorName); + + // If ReflectDecorators is available, use it to check whether 'jsonSetMember' has been used + // on a set. Warn if not. + const reflectedType = isReflectMetadataSupported + ? Reflect.getMetadata('design:type', target, propKey) + : null; + + if (reflectedType != null && reflectedType !== Set && reflectedType !== Object) { + logError(`${decoratorName}: property is not a Set. ${MISSING_REFLECT_CONF_MSG}`); + return; + } + + injectMetadataInformation(target, propKey, { + type: () => SetT(typeThunk()), + emitDefaultValue: options.emitDefaultValue, + isRequired: options.isRequired, + options: extractOptionBase(options), + key: propKey.toString(), + name: options.name ?? propKey.toString(), + deserializer: options.deserializer, + serializer: options.serializer, + }); + }; +} diff --git a/src/metadata.ts b/src/metadata.ts new file mode 100644 index 0000000..e97996b --- /dev/null +++ b/src/metadata.ts @@ -0,0 +1,236 @@ +import {isDirectlySerializableNativeType, isTypeTypedArray, logError, nameof} from './helpers'; +import {OptionsBase} from './options-base'; +import {TypeDescriptor} from './type-descriptor'; +import {IndexedObject, Serializable} from './types'; + +export const METADATA_FIELD_KEY = '__typedJsonJsonObjectMetadataInformation__'; + +export interface CustomDeserializerParams { + fallback: (sourceObject: any, constructor: Serializable | TypeDescriptor) => any; +} + +export interface CustomSerializerParams { + fallback: (sourceObject: any, constructor: Serializable | TypeDescriptor) => any; +} + +export type TypeResolver = ( + sourceObject: IndexedObject, + knownTypes: Map, +) => Function | undefined | null; +export type TypeHintEmitter + = ( + targetObject: IndexedObject, + sourceObject: IndexedObject, + expectedSourceType: Function, + sourceTypeMetadata?: JsonObjectMetadata, + ) => void; + +export interface JsonMemberMetadata { + /** If set, a default value will be emitted for uninitialized members. */ + emitDefaultValue?: boolean | null; + + /** Member name as it appears in the serialized JSON. */ + name: string; + + /** Property or field key of the json member. */ + key: string; + + /** Type descriptor of the member. */ + type?: (() => TypeDescriptor) | null; + + /** If set, indicates that the member must be present when deserializing. */ + isRequired?: boolean | null; + + options?: OptionsBase | null; + + /** Custom deserializer to use. */ + deserializer?: ((json: any, params: CustomDeserializerParams) => any) | null; + + /** Custom serializer to use. */ + serializer?: ((value: any, params: CustomSerializerParams) => any) | null; +} + +export class JsonObjectMetadata { + + dataMembers = new Map(); + + /** Set of known types used for polymorphic deserialization */ + knownTypes = new Set>(); + + /** Known types to be evaluated when (de)serialization occurs */ + knownTypesDeferred: Array<() => TypeDescriptor> = []; + + /** If present override the global function */ + typeHintEmitter?: TypeHintEmitter | null; + /** If present override the global function */ + typeResolver?: TypeResolver | null; + /** Gets or sets the constructor function for the jsonObject. */ + classType: Function; + + /** + * Indicates whether this class was explicitly annotated with @jsonObject + * or implicitly by @jsonMember + */ + isExplicitlyMarked: boolean = false; + + /** + * Indicates whether this type is handled without annotation. This is usually + * used for the builtin types (except for Maps, Sets, and normal Arrays). + */ + isHandledWithoutAnnotation: boolean = false; + + /** Name used to encode polymorphic type */ + name?: string | null; + + options?: OptionsBase | null; + + onDeserializedMethodName?: string | null; + + beforeSerializationMethodName?: string | null; + + initializerCallback?: ((sourceObject: Object, rawSourceObject: Object) => Object) | null; + + constructor( + classType: Function, + ) { + this.classType = classType; + } + + /** + * Gets the name of a class as it appears in a serialized JSON string. + * @param ctor The constructor of a class (with or without jsonObject). + */ + static getJsonObjectName(ctor: Function): string { + const metadata = JsonObjectMetadata.getFromConstructor(ctor); + return metadata === undefined ? nameof(ctor) : nameof(metadata.classType); + } + + /** + * Gets jsonObject metadata information from a class. + * @param ctor The constructor class. + */ + static getFromConstructor(ctor: Serializable): JsonObjectMetadata | undefined { + const prototype = ctor.prototype; + if (prototype == null) { + return; + } + + let metadata: JsonObjectMetadata | undefined; + if (Object.prototype.hasOwnProperty.call(prototype, METADATA_FIELD_KEY)) { + // The class prototype contains own jsonObject metadata + metadata = prototype[METADATA_FIELD_KEY]; + } + + // Ignore implicitly added jsonObject (through jsonMember) + if (metadata?.isExplicitlyMarked === true) { + return metadata; + } + + // In the end maybe it is something which we can handle directly + if (JsonObjectMetadata.doesHandleWithoutAnnotation(ctor)) { + const primitiveMeta = new JsonObjectMetadata(ctor); + primitiveMeta.isExplicitlyMarked = true; + // we do not store the metadata here to not modify builtin prototype + return primitiveMeta; + } + } + + static ensurePresentInPrototype(prototype: IndexedObject): JsonObjectMetadata { + if (Object.prototype.hasOwnProperty.call(prototype, METADATA_FIELD_KEY)) { + return prototype[METADATA_FIELD_KEY]; + } + // Target has no JsonObjectMetadata associated with it yet, create it now. + const objectMetadata = new JsonObjectMetadata(prototype.constructor); + + // Inherit json members and known types from parent @jsonObject (if any). + const parentMetadata: JsonObjectMetadata | undefined = prototype[METADATA_FIELD_KEY]; + if (parentMetadata !== undefined) { + parentMetadata.dataMembers.forEach((memberMetadata, propKey) => { + objectMetadata.dataMembers.set(propKey, memberMetadata); + }); + parentMetadata.knownTypes.forEach((knownType) => { + objectMetadata.knownTypes.add(knownType); + }); + objectMetadata.typeResolver = parentMetadata.typeResolver; + objectMetadata.typeHintEmitter = parentMetadata.typeHintEmitter; + } + + Object.defineProperty(prototype, METADATA_FIELD_KEY, { + enumerable: false, + configurable: false, + writable: false, + value: objectMetadata, + }); + return objectMetadata; + } + + /** + * Gets the known type name of a jsonObject class for type hint. + * @param constructor The constructor class. + */ + static getKnownTypeNameFromType(constructor: Function): string { + const metadata = JsonObjectMetadata.getFromConstructor(constructor); + return metadata === undefined ? nameof(constructor) : nameof(metadata.classType); + } + + private static doesHandleWithoutAnnotation(ctor: Function): boolean { + return isDirectlySerializableNativeType(ctor) || isTypeTypedArray(ctor) + || ctor === DataView || ctor === ArrayBuffer; + } + + processDeferredKnownTypes(): void { + this.knownTypesDeferred.forEach(typeThunk => { + typeThunk().getTypes().forEach(ctor => this.knownTypes.add(ctor)); + }); + this.knownTypesDeferred = []; + } +} + +export function injectMetadataInformation( + prototype: IndexedObject, + propKey: string | symbol, + metadata: JsonMemberMetadata, +) { + // For error messages + const decoratorName = `@jsonMember on ${nameof(prototype.constructor)}.${String(propKey)}`; + + // When a property decorator is applied to a static member, 'constructor' is a constructor + // function. + // See: + // eslint-disable-next-line max-len + // https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md#property-decorators + // ... and static members are not supported here, so abort. + if (typeof prototype as any === 'function') { + logError(`${decoratorName}: cannot use a static property.`); + return; + } + + // Methods cannot be serialized. + // symbol indexing is not supported by ts + if (typeof prototype[propKey as string] === 'function') { + logError(`${decoratorName}: cannot use a method property.`); + return; + } + + // @todo check if metadata is ever undefined, if so, change parameter type + if (metadata as any == null + || (metadata.type === undefined && metadata.deserializer === undefined)) { + logError(`${decoratorName}: JsonMemberMetadata has unknown type.`); + return; + } + + // Add jsonObject metadata to 'constructor' if not yet exists ('constructor' is the prototype). + // NOTE: this will not fire up custom serialization, as 'constructor' must be explicitly marked + // with '@jsonObject' as well. + const objectMetadata = JsonObjectMetadata.ensurePresentInPrototype(prototype); + + if (metadata.deserializer === undefined) { + // If deserializer is not present then type must be + objectMetadata.knownTypesDeferred.push(metadata.type!); + } + + // clear metadata of undefined properties to save memory + (Object.keys(metadata) as Array) + .forEach((key) => (metadata[key] === undefined) && delete metadata[key]); + objectMetadata.dataMembers.set(metadata.name, metadata); +} diff --git a/src/typedjson/options-base.ts b/src/options-base.ts similarity index 57% rename from src/typedjson/options-base.ts rename to src/options-base.ts index b0b5b26..92e986a 100644 --- a/src/typedjson/options-base.ts +++ b/src/options-base.ts @@ -1,3 +1,5 @@ +import {RequiredNoNull} from './helpers'; + /** * This options cascade through the annotations. Options set * in the more specific place override the previous option. @@ -9,16 +11,18 @@ export interface OptionsBase { * will not emit nor store the property if its value is null. * Default: false. */ - preserveNull?: boolean; + preserveNull?: boolean | null; } -const kAllOptions: (keyof OptionsBase)[] = [ +const kAllOptions: Array = [ 'preserveNull', ]; -export function extractOptionBase(from: {[key: string]: any} & OptionsBase): OptionsBase|undefined { +export function extractOptionBase( + from: {[key: string]: any} & OptionsBase, +): OptionsBase | undefined { const options = Object.keys(from) - .filter(key => (kAllOptions as string[]).indexOf(key) > -1) + .filter(key => (kAllOptions as Array).indexOf(key) > -1) .reduce((obj, key) => { obj[key] = from[key]; return obj; @@ -26,9 +30,11 @@ export function extractOptionBase(from: {[key: string]: any} & OptionsBase): Opt return Object.keys(options).length > 0 ? options : undefined; } -export function getDefaultOptionOf(key: K): Required[K] { +export function getDefaultOptionOf( + key: K, +): RequiredNoNull[K] { switch (key) { - case "preserveNull": + case 'preserveNull': return false; } // never reached @@ -37,21 +43,24 @@ export function getDefaultOptionOf(key: K): Require export function getOptionValue( key: K, - options?: OptionsBase, -): Required[K] { - if (options && options[key] != null) return options[key]!; + options?: OptionsBase | null, +): RequiredNoNull[K] { + if (options != null && options[key] as any != null) { + return options[key]!; + } + return getDefaultOptionOf(key); } export function mergeOptions( existing?: OptionsBase, - moreSpecific?: OptionsBase, -): OptionsBase|undefined { - return !moreSpecific + moreSpecific?: OptionsBase | null, +): OptionsBase | undefined { + return moreSpecific == null ? existing - : Object.assign( - {}, - existing, - moreSpecific, - ); + : { + + ...existing, + ...moreSpecific, + }; } diff --git a/src/parser.ts b/src/parser.ts index 1a1ea12..6431f79 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,21 +1,47 @@ -import { Constructor } from "./typedjson/types"; -import { Serializer, TypeHintEmitter } from "./typedjson/serializer"; -import { Deserializer, TypeResolver } from "./typedjson/deserializer"; -import { JsonObjectMetadata } from "./typedjson/metadata"; -import { logError, logWarning, nameof, parseToJSObject } from "./typedjson/helpers"; -import { extractOptionBase, OptionsBase } from "./typedjson/options-base"; - -export type JsonTypes = Object|boolean|string|number|null|undefined; -export { TypeResolver, TypeHintEmitter }; - -export interface ITypedJSONSettings extends OptionsBase -{ +import {defaultTypeResolver, Deserializer} from './deserializer'; +import {logError, logWarning, nameof, parseToJSObject} from './helpers'; +import {createArrayType} from './json-array-member'; +import { + CustomDeserializerParams, + CustomSerializerParams, + JsonObjectMetadata, + TypeHintEmitter, + TypeResolver, +} from './metadata'; +import {extractOptionBase, OptionsBase} from './options-base'; +import {defaultTypeEmitter, Serializer} from './serializer'; +import {ensureTypeDescriptor, MapT, SetT} from './type-descriptor'; +import {Constructor, IndexedObject, Serializable} from './types'; + +export type JsonTypes = Object | boolean | string | number | null | undefined; +export {defaultTypeResolver, defaultTypeEmitter}; + +export interface MappedTypeConverters { + + /** + * Use this deserializer to convert a JSON value to the type. + */ + deserializer?: ((json: any, params: CustomDeserializerParams) => T | null | undefined) | null; + + /** + * Use this serializer to convert a type back to JSON. + */ + serializer?: ((value: T | null | undefined, params: CustomSerializerParams) => any) | null; +} + +export interface ITypedJSONSettings extends OptionsBase { /** * 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; + errorHandler?: ((e: Error) => void) | null; + + /** + * Maps a type to their respective (de)serializer. Prevents you from having to repeat + * (de)serializers. Register additional types with `TypedJSON.mapType`. + */ + mappedTypes?: Map, MappedTypeConverters> | null; /** * Sets a callback that determines the constructor of the correct sub-type of polymorphic @@ -24,290 +50,341 @@ export interface ITypedJSONSettings extends OptionsBase * and look it up in 'knownTypes'. * The constructor of the sub-type should be returned. */ - typeResolver?: TypeResolver; + typeResolver?: TypeResolver | null; - nameResolver?: (ctor: Function) => string; + nameResolver?: ((ctor: Function) => string) | null; /** * 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?: TypeHintEmitter; + typeHintEmitter?: TypeHintEmitter | null; /** * Sets the amount of indentation to use in produced JSON strings. * Default value is 0, or no indentation. */ - indent?: number; + indent?: number | null; - replacer?: (key: string, value: any) => any; + replacer?: ((key: string, value: any) => any) | null; - knownTypes?: Array>; + knownTypes?: Array> | null; } -export class TypedJSON -{ - //#region Static - public static parse( - object: any, rootType: Constructor, settings?: ITypedJSONSettings, - ): T|undefined { +export class TypedJSON { + + private static _globalConfig: ITypedJSONSettings = {}; + + private serializer: Serializer = new Serializer(); + private deserializer: Deserializer = new Deserializer(); + private globalKnownTypes: Array> = []; + private indent: number = 0; + private rootConstructor: Serializable; + 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 rootConstructor The constructor of the root class type. + * @param settings Additional configuration settings. + */ + constructor(rootConstructor: Serializable, settings?: ITypedJSONSettings) { + const rootMetadata = JsonObjectMetadata.getFromConstructor(rootConstructor); + + if (rootMetadata === undefined + || (!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); + + this.config(settings); + } + + static parse( + object: any, + rootType: Serializable, + settings?: ITypedJSONSettings, + ): T | undefined { return new TypedJSON(rootType, settings).parse(object); } - public static parseAsArray( + static parseAsArray( object: any, - elementType: Constructor, + elementType: Serializable, settings?: ITypedJSONSettings, - dimensions?: 1 - ): T[]; - public static parseAsArray( + dimensions?: 1, + ): Array; + static parseAsArray( object: any, - elementType: Constructor, - settings: ITypedJSONSettings|undefined, - dimensions: 2 - ): T[][]; - public static parseAsArray( + elementType: Serializable, + settings: ITypedJSONSettings | undefined, + dimensions: 2, + ): Array>; + static parseAsArray( object: any, - elementType: Constructor, - settings: ITypedJSONSettings|undefined, - dimensions: 3 - ): T[][][]; - public static parseAsArray( + elementType: Serializable, + settings: ITypedJSONSettings | undefined, + dimensions: 3, + ): Array>>; + static parseAsArray( object: any, - elementType: Constructor, - settings: ITypedJSONSettings|undefined, - dimensions: 4 - ): T[][][][]; - public static parseAsArray( + elementType: Serializable, + settings: ITypedJSONSettings | undefined, + dimensions: 4, + ): Array>>>; + static parseAsArray( object: any, - elementType: Constructor, - settings: ITypedJSONSettings|undefined, - dimensions: 5 - ): T[][][][][]; - public static parseAsArray( + elementType: Serializable, + settings: ITypedJSONSettings | undefined, + dimensions: 5, + ): Array>>>>; + static parseAsArray( object: any, - elementType: Constructor, + elementType: Serializable, settings?: ITypedJSONSettings, - dimensions?: number - ): any[] { + dimensions?: number, + ): Array { return new TypedJSON(elementType, settings).parseAsArray(object, dimensions as any); } - public static parseAsSet( - object: any, elementType: Constructor, settings?: ITypedJSONSettings, + static parseAsSet( + object: any, + elementType: Serializable, + settings?: ITypedJSONSettings, ): Set { return new TypedJSON(elementType, settings).parseAsSet(object); } - public static parseAsMap( + static parseAsMap( object: any, - keyType: Constructor, - valueType: Constructor, + keyType: Serializable, + valueType: Serializable, settings?: ITypedJSONSettings, ): Map { return new TypedJSON(valueType, settings).parseAsMap(object, keyType); } - public static toPlainJson( - object: T, rootType: Constructor, settings?: ITypedJSONSettings, + static toPlainJson( + object: T, + rootType: Serializable, + 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[] { + static toPlainArray( + object: Array, + elementType: Serializable, + dimensions?: 1, + settings?: ITypedJSONSettings, + ): Array; + static toPlainArray( + object: Array>, + elementType: Serializable, + dimensions: 2, + settings?: ITypedJSONSettings, + ): Array>; + static toPlainArray( + object: Array>>, + elementType: Serializable, + dimensions: 3, + settings?: ITypedJSONSettings, + ): Array>>; + static toPlainArray( + object: Array>>>, + elementType: Serializable, + dimensions: 4, settings?: ITypedJSONSettings, + ): Array>>>; + static toPlainArray( + object: Array>>>>, + elementType: Serializable, + dimensions: 5, + settings?: ITypedJSONSettings, + ): Array>>>>; + static toPlainArray( + object: Array, + elementType: Serializable, + dimensions: number, + settings?: ITypedJSONSettings, + ): Array; + static toPlainArray( + object: Array, + elementType: Serializable, + dimensions?: any, + settings?: ITypedJSONSettings, + ): Array { return new TypedJSON(elementType, settings).toPlainArray(object, dimensions); } - public static toPlainSet( - object: Set, elementType: Constructor, settings?: ITypedJSONSettings, - ): Object[]|undefined { + static toPlainSet( + object: Set, + elementType: Serializable, + settings?: ITypedJSONSettings, + ): Array | undefined { return new TypedJSON(elementType, settings).toPlainSet(object); } - public static toPlainMap( + static toPlainMap( object: Map, - keyCtor: Constructor, - valueCtor: Constructor, + keyCtor: Serializable, + valueCtor: Serializable, settings?: ITypedJSONSettings, - ): { key: any, value: any }[]|undefined { + ): IndexedObject | Array<{key: any; value: any}> | undefined { return new TypedJSON(valueCtor, settings).toPlainMap(object, keyCtor); } - public static stringify( - object: T, rootType: Constructor, settings?: ITypedJSONSettings, + static stringify( + object: T, + rootType: Serializable, + settings?: ITypedJSONSettings, ): string { return new TypedJSON(rootType, settings).stringify(object); } - public static stringifyAsArray( - object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings, + static stringifyAsArray( + object: Array, + elementType: Serializable, + dimensions?: 1, + settings?: ITypedJSONSettings, ): string; - public static stringifyAsArray( - object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings, + static stringifyAsArray( + object: Array>, + elementType: Serializable, + dimensions: 2, + settings?: ITypedJSONSettings, ): string; - public static stringifyAsArray( - object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings, + static stringifyAsArray( + object: Array>>, + elementType: Serializable, + dimensions: 3, + settings?: ITypedJSONSettings, ): string; - public static stringifyAsArray( - object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings, + static stringifyAsArray( + object: Array>>>, + elementType: Serializable, + dimensions: 4, + settings?: ITypedJSONSettings, ): string; - public static stringifyAsArray( - object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings, + static stringifyAsArray( + object: Array>>>>, + elementType: Serializable, + dimensions: 5, + settings?: ITypedJSONSettings, ): string; - public static stringifyAsArray( - object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings, + static stringifyAsArray( + object: Array, + elementType: Serializable, + dimensions: number, settings?: ITypedJSONSettings, ): string; - public static stringifyAsArray( - object: any[], elementType: Constructor, dimensions?: any, settings?: ITypedJSONSettings, + static stringifyAsArray( + object: Array, + elementType: Serializable, + dimensions?: any, + settings?: ITypedJSONSettings, ): string { return new TypedJSON(elementType, settings).stringifyAsArray(object, dimensions); } - public static stringifyAsSet( - object: Set, elementType: Constructor, settings?: ITypedJSONSettings, + static stringifyAsSet( + object: Set, + elementType: Serializable, + settings?: ITypedJSONSettings, ): string { return new TypedJSON(elementType, settings).stringifyAsSet(object); } - public static stringifyAsMap( + static stringifyAsMap( object: Map, - keyCtor: Constructor, - valueCtor: Constructor, + keyCtor: Serializable, + valueCtor: Serializable, 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; - } + static setGlobalConfig(config: ITypedJSONSettings) { + Object.assign(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. + * Map a type to its (de)serializer. */ - 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."); + static mapType(type: Serializable, converters: MappedTypeConverters): void { + if (this._globalConfig.mappedTypes == null) { + this._globalConfig.mappedTypes = new Map(); } - this.nameResolver = (ctor) => nameof(ctor); - this.rootConstructor = rootConstructor; - this.errorHandler = (error) => logError(error); - - if (settings) - { - this.config(settings); - } - else if (TypedJSON._globalConfig) - { - this.config({}); - } + this._globalConfig.mappedTypes.set(type, converters); } /** * 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), - )); - } + config(settings?: ITypedJSONSettings) { + settings = { + ...TypedJSON._globalConfig, + ...settings, + }; + + if (settings.knownTypes != null + && TypedJSON._globalConfig.knownTypes != null) { + // Merge known-types (also de-duplicate them, so Array -> Set -> Array). + settings.knownTypes = Array.from(new Set( + settings.knownTypes.concat(TypedJSON._globalConfig.knownTypes), + )); } const options = extractOptionBase(settings); this.serializer.options = options; this.deserializer.options = options; - if (settings.errorHandler) - { + if (settings.errorHandler != null) { 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.replacer != null) { + this.replacer = settings.replacer; + } + if (settings.typeResolver != null) { + this.deserializer.setTypeResolver(settings.typeResolver); + } + if (settings.typeHintEmitter != null) { + this.serializer.setTypeHintEmitter(settings.typeHintEmitter); + } + if (settings.indent != null) { + this.indent = settings.indent; + } + + if (settings.mappedTypes != null) { + settings.mappedTypes.forEach((upDown, type) => { + this.setSerializationStrategies(type, upDown); + }); + } - if (settings.nameResolver) - { + if (settings.nameResolver != null) { this.nameResolver = settings.nameResolver; this.deserializer.setNameResolver(settings.nameResolver); - // this.serializer.set } - if (settings.knownTypes) - { + if (settings.knownTypes != null) { // 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) - { + settings.knownTypes.forEach((knownType: any, i) => { + if (typeof knownType === 'undefined' || knownType === null) { logWarning( - `TypedJSON.config: 'knownTypes' contains an undefined/null value (element ${i}).`); + `TypedJSON.config: 'knownTypes' contains an undefined/null value` + + ` (element ${i}).`, + ); } }); @@ -315,119 +392,65 @@ export class TypedJSON } } + mapType(type: Serializable, converters: MappedTypeConverters): void { + this.setSerializationStrategies(type, converters); + } + /** * 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 - { + 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(); + let result: T | undefined; - 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) - { + try { + result = this.deserializer.convertSingleValue( + json, + ensureTypeDescriptor(this.rootConstructor), + this.getKnownTypes(), + ) 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[] - { + parseAsArray(object: any, dimensions?: 1): Array; + parseAsArray(object: any, dimensions: 2): Array>; + parseAsArray(object: any, dimensions: 3): Array>>; + parseAsArray(object: any, dimensions: 4): Array>>>; + parseAsArray(object: any, dimensions: 5): Array>>>>; + parseAsArray(object: any, dimensions: number): Array; + parseAsArray(object: any, dimensions: number = 1): Array { 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 []; + return this.deserializer.convertSingleValue( + json, + createArrayType(ensureTypeDescriptor(this.rootConstructor), dimensions), + this._mapKnownTypes(this.globalKnownTypes), + ); } - public parseAsSet(object: any): Set - { + 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(); + return this.deserializer.convertSingleValue( + json, + SetT(this.rootConstructor), + this._mapKnownTypes(this.globalKnownTypes), + ); } - public parseAsMap(object: any, keyConstructor: Constructor): Map - { + parseAsMap(object: any, keyConstructor: Serializable): 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(); + return this.deserializer.convertSingleValue( + json, + MapT(keyConstructor, this.rootConstructor), + this._mapKnownTypes(this.globalKnownTypes), + ); } /** @@ -435,60 +458,57 @@ export class TypedJSON * @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 - { + toPlainJson(object: T): JsonTypes { + try { return this.serializer.convertSingleValue( object, - {selfType: this.rootConstructor}, + ensureTypeDescriptor(this.rootConstructor), ); - } - catch (e) - { + } 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) - { + toPlainArray(object: Array, dimensions?: 1): Array; + toPlainArray(object: Array>, dimensions: 2): Array>; + toPlainArray(object: Array>>, dimensions: 3): Array>>; + toPlainArray( + object: Array>>>, + dimensions: 4, + ): Array>>>; + toPlainArray( + object: Array>>>>, + dimensions: 5, + ): Array>>>>; + toPlainArray(object: Array, dimensions: 1 | 2 | 3 | 4 | 5 = 1): Array | undefined { + try { + return this.serializer.convertSingleValue( + object, + createArrayType(ensureTypeDescriptor(this.rootConstructor), dimensions), + ); + } catch (e) { this.errorHandler(e); } } - public toPlainSet(object: Set): Object[]|undefined - { - try - { - return this.serializer.convertAsSet(object, this.rootConstructor); - } - catch (e) - { + toPlainSet(object: Set): Array | undefined { + try { + return this.serializer.convertSingleValue(object, SetT(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) - { + toPlainMap( + object: Map, + keyConstructor: Serializable, + ): IndexedObject | Array<{key: any; value: any}> | undefined { + try { + return this.serializer.convertSingleValue( + object, + MapT(keyConstructor, this.rootConstructor), + ); + } catch (e) { this.errorHandler(e); } } @@ -500,8 +520,7 @@ export class TypedJSON * @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 - { + stringify(object: T): string { const result = this.toPlainJson(object); if (result === undefined) { return ''; @@ -509,32 +528,81 @@ export class TypedJSON 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 - { + stringifyAsArray(object: Array, dimensions?: 1): string; + stringifyAsArray(object: Array>, dimensions: 2): string; + stringifyAsArray(object: Array>>, dimensions: 3): string; + stringifyAsArray(object: Array>>>, dimensions: 4): string; + stringifyAsArray(object: Array>>>>, dimensions: 5): string; + stringifyAsArray(object: Array, dimensions: any): string { return JSON.stringify(this.toPlainArray(object, dimensions), this.replacer, this.indent); } - public stringifyAsSet(object: Set): string - { + stringifyAsSet(object: Set): string { return JSON.stringify(this.toPlainSet(object), this.replacer, this.indent); } - public stringifyAsMap(object: Map, keyConstructor: Constructor): string - { + stringifyAsMap(object: Map, keyConstructor: Serializable): string { return JSON.stringify(this.toPlainMap(object, keyConstructor), this.replacer, this.indent); } - private _mapKnownTypes(constructors: Array>) - { - let map = new Map>(); + private getKnownTypes(): Map { + const rootMetadata = JsonObjectMetadata.getFromConstructor(this.rootConstructor); + const knownTypes = new Map(); + + this.globalKnownTypes.filter(ktc => ktc).forEach(knownTypeCtor => { + knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor); + }); + + if (rootMetadata !== undefined) { + rootMetadata.processDeferredKnownTypes(); + rootMetadata.knownTypes.forEach(knownTypeCtor => { + knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor); + }); + } + return knownTypes; + } + + private _mapKnownTypes(constructors: Array>) { + const map = new Map>(); constructors.filter(ctor => ctor).forEach(ctor => map.set(this.nameResolver(ctor), ctor)); return map; } + + private setSerializationStrategies( + type: Serializable, + converters: MappedTypeConverters, + ): void { + if (converters.deserializer != null) { + this.deserializer.setDeserializationStrategy( + type, + value => converters.deserializer!( + value, + { + fallback: (so, td) => this.deserializer.convertSingleValue( + so, + ensureTypeDescriptor(td), + this.getKnownTypes(), + ), + }, + ), + ); + } + + if (converters.serializer != null) { + this.serializer.setSerializationStrategy( + type, + value => converters.serializer!( + value, + { + fallback: (so, td) => this.serializer.convertSingleValue( + so, + ensureTypeDescriptor(td), + ), + }, + ), + ); + } + } } diff --git a/src/serializer.ts b/src/serializer.ts new file mode 100644 index 0000000..c3dfeae --- /dev/null +++ b/src/serializer.ts @@ -0,0 +1,474 @@ +import { + identity, + isInstanceOf, + isValueDefined, + logError, + nameof, +} from './helpers'; +import {JsonObjectMetadata, TypeHintEmitter} from './metadata'; +import {getOptionValue, mergeOptions, OptionsBase} from './options-base'; +import { + AnyT, + ArrayTypeDescriptor, + ConcreteTypeDescriptor, + ensureTypeDescriptor, + MapShape, + MapTypeDescriptor, + SetTypeDescriptor, + TypeDescriptor, +} from './type-descriptor'; +import {IndexedObject, Serializable} from './types'; + +export function defaultTypeEmitter( + targetObject: IndexedObject, + sourceObject: IndexedObject, + expectedSourceType: Function, + sourceTypeMetadata?: JsonObjectMetadata, +) { + // 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) { + targetObject.__type = sourceTypeMetadata?.name ?? nameof(sourceObject.constructor); + } +} + +/** + * @param sourceObject The original object that should be serialized. + * @param typeDescriptor Instance of TypeDescriptor containing information about expected + * serialization. + * @param memberName Name of the object being serialized, used for debugging purposes. + * @param serializer Serializer instance, aiding with recursive serialization. + * @param memberOptions If converted as a member, the member options. + */ +export type SerializerFn = ( + sourceObject: T, + typeDescriptor: TD, + memberName: string, + serializer: Serializer, + memberOptions?: OptionsBase, +) => Raw; + +/** + * 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 + */ +export class Serializer { + options?: OptionsBase; + private typeHintEmitter: TypeHintEmitter = defaultTypeEmitter; + private errorHandler: (error: Error) => void = logError; + private serializationStrategy = new Map< + Serializable, + SerializerFn + >([ + // primitives + [AnyT.ctor, identity], + [Date, identity], + [Number, identity], + [String, identity], + [Boolean, identity], + + [ArrayBuffer, convertAsArrayBuffer], + [DataView, convertAsDataView], + + [Array, convertAsArray], + [Set, convertAsSet], + [Map, convertAsMap], + + // typed arrays + [Float32Array, convertAsTypedArray], + [Float64Array, convertAsTypedArray], + [Int8Array, convertAsTypedArray], + [Uint8Array, convertAsTypedArray], + [Uint8ClampedArray, convertAsTypedArray], + [Int16Array, convertAsTypedArray], + [Uint16Array, convertAsTypedArray], + [Int32Array, convertAsTypedArray], + [Uint32Array, convertAsTypedArray], + ]); + + setSerializationStrategy( + type: Serializable, + serializer: SerializerFn, + ) { + this.serializationStrategy.set(type, serializer); + } + + setTypeHintEmitter(typeEmitterCallback: TypeHintEmitter) { + if (typeof typeEmitterCallback as any !== 'function') { + throw new TypeError('\'typeEmitterCallback\' is not a function.'); + } + + this.typeHintEmitter = typeEmitterCallback; + } + + getTypeHintEmitter(): TypeHintEmitter { + return this.typeHintEmitter; + } + + setErrorHandler(errorHandlerCallback: (error: Error) => void) { + if (typeof errorHandlerCallback as any !== 'function') { + throw new TypeError('\'errorHandlerCallback\' is not a function.'); + } + + this.errorHandler = errorHandlerCallback; + } + + getErrorHandler(): (error: Error) => void { + return this.errorHandler; + } + + retrievePreserveNull(memberOptions?: OptionsBase): boolean { + return getOptionValue('preserveNull', mergeOptions(this.options, memberOptions)); + } + + /** + * Convert a value of any supported serializable type. + * The value type will be detected, and the correct serialization method will be called. + */ + convertSingleValue( + sourceObject: any, + typeDescriptor: TypeDescriptor, + memberName: string = 'object', + memberOptions?: OptionsBase, + ): any { + if (this.retrievePreserveNull(memberOptions) && sourceObject === null) { + return null; + } + if (!isValueDefined(sourceObject)) { + return; + } + + if (!isInstanceOf(sourceObject, typeDescriptor.ctor)) { + const expectedName = nameof(typeDescriptor.ctor); + const actualName = nameof(sourceObject.constructor); + + this.errorHandler(new TypeError( + `Could not serialize '${memberName}': expected '${expectedName}',` + + ` got '${actualName}'.`, + )); + return; + } + + const serializer = this.serializationStrategy.get(typeDescriptor.ctor); + if (serializer !== undefined) { + return serializer(sourceObject, typeDescriptor, memberName, this, memberOptions); + } + // if not present in the strategy do property by property serialization + if (typeof sourceObject === 'object') { + return convertAsObject(sourceObject, typeDescriptor, memberName, this, memberOptions); + } + + let error = `Could not serialize '${memberName}'; don't know how to serialize type`; + + if (typeDescriptor.hasFriendlyName()) { + error += ` '${typeDescriptor.ctor.name}'`; + } + + this.errorHandler(new TypeError(`${error}.`)); + } +} + +/** + * Performs the conversion of a typed object (usually a class instance) to a simple + * javascript object for serialization. + */ +function convertAsObject( + sourceObject: IndexedObject, + typeDescriptor: ConcreteTypeDescriptor, + memberName: string, + serializer: Serializer, + memberOptions?: OptionsBase, +) { + let sourceTypeMetadata: JsonObjectMetadata | undefined; + let targetObject: IndexedObject; + let typeHintEmitter = serializer.getTypeHintEmitter(); + + if (sourceObject.constructor !== typeDescriptor.ctor + && sourceObject instanceof typeDescriptor.ctor) { + // 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 = JsonObjectMetadata.getFromConstructor(sourceObject.constructor); + } else { + sourceTypeMetadata = JsonObjectMetadata.getFromConstructor(typeDescriptor.ctor); + } + + if (sourceTypeMetadata === undefined) { + // 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 = {...sourceObject}; + } else { + const beforeSerializationMethodName = sourceTypeMetadata.beforeSerializationMethodName; + if (beforeSerializationMethodName != null) { + if (typeof (sourceObject as any)[beforeSerializationMethodName] === 'function') { + // check for member first + (sourceObject as any)[beforeSerializationMethodName](); + } else if (typeof (sourceObject.constructor as any)[beforeSerializationMethodName] + === 'function') { + // check for static + (sourceObject.constructor as any)[beforeSerializationMethodName](); + } else { + serializer.getErrorHandler()(new TypeError( + `beforeSerialization callback '` + + `${nameof(sourceTypeMetadata.classType)}.${beforeSerializationMethodName}` + + `' is not a method.`, + )); + } + } + + const sourceMeta = 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 = {}; + + const classOptions = mergeOptions(serializer.options, sourceMeta.options); + if (sourceMeta.typeHintEmitter != null) { + typeHintEmitter = sourceMeta.typeHintEmitter; + } + + sourceMeta.dataMembers.forEach((objMemberMetadata) => { + const objMemberOptions = mergeOptions(classOptions, objMemberMetadata.options); + let serialized; + if (objMemberMetadata.serializer != null) { + serialized = objMemberMetadata.serializer( + sourceObject[objMemberMetadata.key], + { + fallback: (so, td) => serializer.convertSingleValue( + so, + ensureTypeDescriptor(td), + ), + }, + ); + } else if (objMemberMetadata.type == null) { + throw new TypeError( + `Could not serialize ${objMemberMetadata.name}, there is` + + ` no constructor nor serialization function to use.`, + ); + } else { + serialized = serializer.convertSingleValue( + sourceObject[objMemberMetadata.key], + objMemberMetadata.type(), + `${nameof(sourceMeta.classType)}.${objMemberMetadata.key}`, + objMemberOptions, + ); + } + + if ((serializer.retrievePreserveNull(objMemberOptions) && serialized === null) + || isValueDefined(serialized) + ) { + targetObject[objMemberMetadata.name] = serialized; + } + }); + } + + // Add type-hint. + typeHintEmitter(targetObject, sourceObject, typeDescriptor.ctor, sourceTypeMetadata); + + return targetObject; +} + +/** + * Performs the conversion of an array of typed objects (or primitive values) to an array of simple + * javascript objects + * (or primitive values) for serialization. + */ +function convertAsArray( + sourceObject: Array, + typeDescriptor: TypeDescriptor, + memberName: string, + serializer: Serializer, + memberOptions?: OptionsBase, +): Array { + if (!(typeDescriptor instanceof ArrayTypeDescriptor)) { + throw new TypeError( + `Could not serialize ${memberName} as Array: incorrect TypeDescriptor detected, please` + + ' use proper annotation or function for this type', + ); + } + if (typeDescriptor.elementType as any == null) { + 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((element, i) => { + if (!(serializer.retrievePreserveNull(memberOptions) && element === null) + && !isInstanceOf(element, typeDescriptor.elementType.ctor) + ) { + const expectedTypeName = nameof(typeDescriptor.elementType.ctor); + // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions + const actualTypeName = element && nameof(element.constructor); + throw new TypeError(`Could not serialize ${memberName}[${i}]:` + + ` expected '${expectedTypeName}', got '${actualTypeName}'.`); + } + }); + + return sourceObject.map((element, i) => { + return serializer.convertSingleValue( + element, + typeDescriptor.elementType, + `${memberName}[${i}]`, + memberOptions, + ); + }); +} + +/** + * Performs the conversion of a set of typed objects (or primitive values) into an array + * of simple javascript objects. + * @returns + */ +function convertAsSet( + sourceObject: Set, + typeDescriptor: TypeDescriptor, + memberName: string, + serializer: Serializer, + memberOptions?: OptionsBase, +): Array { + if (!(typeDescriptor instanceof SetTypeDescriptor)) { + throw new TypeError( + `Could not serialize ${memberName} as Set: incorrect TypeDescriptor detected, please` + + ' use proper annotation or function for this type', + ); + } + if (typeDescriptor.elementType as any == null) { + throw new TypeError( + `Could not serialize ${memberName} as Set: missing element type definition.`, + ); + } + + memberName += '[]'; + const resultArray: Array = []; + + // 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((element) => { + const resultElement = serializer.convertSingleValue( + element, + typeDescriptor.elementType, + memberName, + memberOptions, + ); + + // 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; +} + +/** + * Performs the conversion of a map of typed objects (or primitive values) into an array + * of simple javascript objects with `key` and `value` properties. + */ +function convertAsMap( + sourceObject: Map, + typeDescriptor: TypeDescriptor, + memberName: string, + serializer: Serializer, + memberOptions?: OptionsBase, +): IndexedObject | Array<{key: any; value: any}> { + if (!(typeDescriptor instanceof MapTypeDescriptor)) { + throw new TypeError( + `Could not serialize ${memberName} as Map: incorrect TypeDescriptor detected, please` + + ' use proper annotation or function for this type', + ); + } + if (typeDescriptor.valueType as any == null) { // @todo Check type + throw new TypeError( + `Could not serialize ${memberName} as Map: missing value type definition.`, + ); + } + + if (typeDescriptor.keyType as any == null) { // @todo Check type + throw new TypeError( + `Could not serialize ${memberName} as Map: missing key type definition.`, + ); + } + + const keyMemberName = `${memberName}[].key`; + const valueMemberName = `${memberName}[].value`; + const resultShape = typeDescriptor.getCompleteOptions().shape; + const result = resultShape === MapShape.OBJECT ? ({} as IndexedObject) : []; + const preserveNull = serializer.retrievePreserveNull(memberOptions); + + // Convert each *entry* in the map to a simple javascript object with key and value properties. + sourceObject.forEach((value, key) => { + const resultKeyValuePairObj = { + key: serializer.convertSingleValue( + key, + typeDescriptor.keyType, + keyMemberName, + memberOptions, + ), + value: serializer.convertSingleValue( + value, + typeDescriptor.valueType, + valueMemberName, + memberOptions, + ), + }; + + // We are not going to emit entries with undefined keys OR undefined values. + const keyDefined = isValueDefined(resultKeyValuePairObj.key); + const valueDefined = (resultKeyValuePairObj.value === null && preserveNull) + || isValueDefined(resultKeyValuePairObj.value); + if (keyDefined && valueDefined) { + if (resultShape === MapShape.OBJECT) { + result[resultKeyValuePairObj.key] = resultKeyValuePairObj.value; + } else { + result.push(resultKeyValuePairObj); + } + } + }); + + return result; +} + +/** + * 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, ... }". + */ +function convertAsTypedArray(sourceObject: ArrayBufferView) { + return Array.from(sourceObject as any); +} + +/** + * Performs the conversion of a raw ArrayBuffer to a string. + */ +function convertAsArrayBuffer(buffer: ArrayBuffer) { + // ArrayBuffer -> 16-bit character codes -> character array -> joined string. + return Array.from(new Uint16Array(buffer)) + .map(charCode => String.fromCharCode(charCode)).join(''); +} + +/** + * Performs the conversion of DataView, converting its internal ArrayBuffer to a string and + * returning that string. + */ +function convertAsDataView(dataView: DataView) { + return convertAsArrayBuffer(dataView.buffer); +} diff --git a/src/typedjson/to-json.ts b/src/to-json.ts similarity index 83% rename from src/typedjson/to-json.ts rename to src/to-json.ts index 905c2bc..942330e 100644 --- a/src/typedjson/to-json.ts +++ b/src/to-json.ts @@ -1,4 +1,4 @@ -import { TypedJSON } from "../parser"; +import {TypedJSON} from './parser'; /** * Options for the @toJson decorator. @@ -23,7 +23,8 @@ export function toJson(target: Function): void; * @param options for configuring the toJSON creation. */ export function toJson(options: IToJsonOptions): ((target: Function) => void); -export function toJson(optionsOrTarget: IToJsonOptions | Function +export function toJson( + optionsOrTarget: IToJsonOptions | Function, ): ((target: Function) => void) | void { if (typeof optionsOrTarget === 'function') { // used directly @@ -33,14 +34,14 @@ export function toJson(optionsOrTarget: IToJsonOptions | Funct // used as a factory return (target: Function) => { toJsonDecorator(target, optionsOrTarget); - } + }; } function toJsonDecorator(target: Function, options: IToJsonOptions): void { - if (!options.overwrite && target.prototype.toJSON) { + if (options.overwrite !== true && target.prototype.toJSON !== undefined) { throw new Error(`${target.name} already has toJSON defined!`); } - target.prototype.toJSON = function () { + target.prototype.toJSON = function toJSON() { return TypedJSON.toPlainJson(this, Object.getPrototypeOf(this).constructor); - } + }; } diff --git a/src/type-descriptor.ts b/src/type-descriptor.ts new file mode 100644 index 0000000..28f1ec6 --- /dev/null +++ b/src/type-descriptor.ts @@ -0,0 +1,156 @@ +import {LAZY_TYPE_EXPLANATION} from './helpers'; +import {Serializable} from './types'; + +export abstract class TypeDescriptor { + protected constructor(readonly ctor: Function) { + } + + getTypes(): Array { + return [this.ctor]; + } + + hasFriendlyName(): boolean { + return this.ctor.name !== 'Object'; + } +} + +export type Typelike = TypeDescriptor | Function; + +export class ConcreteTypeDescriptor extends TypeDescriptor { + // eslint-disable-next-line @typescript-eslint/no-useless-constructor + constructor(ctor: Function) { + super(ctor); + } +} + +export abstract class GenericTypeDescriptor extends TypeDescriptor { + protected constructor(ctor: Function) { + super(ctor); + } +} + +export class ArrayTypeDescriptor extends GenericTypeDescriptor { + constructor(readonly elementType: TypeDescriptor) { + super(Array); + } + + getTypes(): Array { + return super.getTypes().concat(this.elementType.getTypes()); + } +} + +export function ArrayT(elementType: Typelike): ArrayTypeDescriptor { + return new ArrayTypeDescriptor(ensureTypeDescriptor(elementType)); +} + +export class SetTypeDescriptor extends GenericTypeDescriptor { + constructor(readonly elementType: TypeDescriptor) { + super(Set); + } + + getTypes(): Array { + return super.getTypes().concat(this.elementType.getTypes()); + } +} + +export function SetT(elementType: Typelike): SetTypeDescriptor { + return new SetTypeDescriptor(ensureTypeDescriptor(elementType)); +} + +export const enum MapShape { + /** + * A map will be serialized as an array of {key: ..., value: ...} objects. + */ + ARRAY, + + /** + * A map will be serialized as a JSON object. + */ + OBJECT, +} + +export interface MapOptions { + /** + * How the map should be serialized. Default is ARRAY. + */ + shape: MapShape; +} + +export class MapTypeDescriptor extends GenericTypeDescriptor { + constructor( + readonly keyType: TypeDescriptor, + readonly valueType: TypeDescriptor, + readonly options?: Partial, + ) { + super(Map); + } + + getTypes(): Array { + return super.getTypes().concat(this.keyType.getTypes(), this.valueType.getTypes()); + } + + getCompleteOptions(): MapOptions { + return { + shape: this.options?.shape ?? MapShape.ARRAY, + }; + } +} + +export function MapT( + keyType: Typelike, + valueType: Typelike, + options?: Partial, +): MapTypeDescriptor { + return new MapTypeDescriptor( + ensureTypeDescriptor(keyType), + ensureTypeDescriptor(valueType), + options, + ); +} + +export const AnyT = new ConcreteTypeDescriptor(() => undefined); + +// TODO support for dictionary types ie. maps that are plain objects +// export class DictionaryTypeDescriptor extends GenericTypeDescriptor { +// constructor(public readonly elementType: TypeDescriptor) { +// super(Object); +// } +// +// getTypes(): Function[] { +// return super.getTypes().concat(this.elementType.getTypes()); +// } +// } +// +// export function DictT(elementType: Typelike): DictionaryTypeDescriptor { +// return new DictionaryTypeDescriptor(ensureTypeDescriptor(elementType)); +// } + +export type TypeThunk = () => Serializable | TypeDescriptor; +export type MaybeTypeThunk = Serializable | TypeDescriptor | TypeThunk; + +export function isTypelike(type: any): type is Typelike { + return type != null && (typeof type === 'function' || type instanceof TypeDescriptor); +} + +export function isTypeThunk(candidate: any): candidate is TypeThunk { + return typeof candidate === 'function' && candidate.name === ''; +} + +export function ensureTypeDescriptor(type: Typelike): TypeDescriptor { + return type instanceof TypeDescriptor ? type : new ConcreteTypeDescriptor(type); +} + +export function ensureTypeThunk( + typeThunkOrSerializable: MaybeTypeThunk | null | undefined, + decoratorName: string, +): TypeThunk { + if (typeThunkOrSerializable == null) { + throw new Error(`No type given on ${decoratorName}. ${LAZY_TYPE_EXPLANATION}`); + } + + if (isTypeThunk(typeThunkOrSerializable)) { + return typeThunkOrSerializable; + } + + return () => typeThunkOrSerializable; +} diff --git a/src/typedjson.ts b/src/typedjson.ts deleted file mode 100644 index 307ab6b..0000000 --- a/src/typedjson.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { TypedJSON, ITypedJSONSettings, JsonTypes, TypeResolver, TypeHintEmitter } from "./parser"; -export { jsonObject } from "./typedjson/json-object"; -export { jsonMember } from "./typedjson/json-member"; -export { jsonArrayMember } from "./typedjson/json-array-member"; -export { jsonSetMember } from "./typedjson/json-set-member"; -export { jsonMapMember } from "./typedjson/json-map-member"; -export { toJson } from "./typedjson/to-json"; diff --git a/src/typedjson/deserializer.ts b/src/typedjson/deserializer.ts deleted file mode 100644 index 33c2b67..0000000 --- a/src/typedjson/deserializer.ts +++ /dev/null @@ -1,623 +0,0 @@ -import { nameof, logError, isSubtypeOf, isValueDefined, isDirectlyDeserializableNativeType } from "./helpers"; -import { Constructor, IndexedObject } from "./types"; -import { JsonObjectMetadata } from "./metadata"; -import { getOptionValue, mergeOptions, OptionsBase } from "./options-base"; - -export interface IScopeTypeInfo -{ - selfConstructor: Function; - elementConstructor?: Function[]; - keyConstructor?: Function; - knownTypes: Map; -} - -export type TypeResolver = (sourceObject: Object, knownTypes: Map) => Function|undefined|null; - -function defaultTypeResolver(sourceObject: any, knownTypes: Map): Function|undefined { - if (sourceObject.__type) return knownTypes.get(sourceObject.__type); -} - -/** - * Utility class, converts a simple/untyped javascript object-tree to a typed object-tree. - * It is used after parsing a JSON-string. - */ -export class Deserializer -{ - public options?: OptionsBase; - - private _typeResolver: TypeResolver = defaultTypeResolver; - private _nameResolver?: (ctor: Function) => string; - private _errorHandler: (error: Error) => void = logError; - - public setNameResolver(nameResolverCallback: (ctor: Function) => string) - { - this._nameResolver = nameResolverCallback; - } - - public setTypeResolver(typeResolverCallback: TypeResolver) - { - if (typeof typeResolverCallback !== "function") - { - throw new TypeError("'typeResolverCallback' is not a function."); - } - - this._typeResolver = typeResolverCallback; - } - - public setErrorHandler(errorHandlerCallback: (error: Error) => void) - { - if (typeof errorHandlerCallback !== "function") - { - throw new TypeError("'errorHandlerCallback' is not a function."); - } - - this._errorHandler = errorHandlerCallback; - } - - public convertAsObject( - sourceObject: IndexedObject, - sourceObjectTypeInfo: IScopeTypeInfo, - objectName = "object", - memberOptions?: OptionsBase, - ) { - if (typeof sourceObject !== "object" || sourceObject === null) - { - this._errorHandler(new TypeError(`Cannot deserialize ${objectName}: 'sourceObject' must be a defined object.`)); - return undefined; - } - - let expectedSelfType = sourceObjectTypeInfo.selfConstructor; - let sourceObjectMetadata = JsonObjectMetadata.getFromConstructor(expectedSelfType); - let 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), - ); - } - - // Check if a type-hint is available from the source object. - const 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 = JsonObjectMetadata.getFromConstructor(typeFromTypeHint); - - if (sourceObjectMetadata) - { - // Also merge new known types from subtype. - knownTypeConstructors = this._mergeKnownTypes( - knownTypeConstructors, - this._createKnownTypesMap(sourceObjectMetadata.knownTypes), - ); - } - } - } - - if (sourceObjectMetadata && sourceObjectMetadata.isExplicitlyMarked) - { - const sourceMetadata = sourceObjectMetadata; - // Strong-typed deserialization available, get to it. - // First deserialize properties into a temporary object. - const sourceObjectWithDeserializedProperties = {} as IndexedObject; - - const classOptions = mergeOptions(this.options, sourceMetadata.options); - - // Deserialize by expected properties. - sourceMetadata.dataMembers.forEach((objMemberMetadata, propKey) => - { - const objMemberValue = sourceObject[propKey]; - const objMemberDebugName = `${nameof(sourceMetadata.classType)}.${propKey}`; - const objMemberOptions = mergeOptions(classOptions, objMemberMetadata.options); - - let revivedValue; - if (objMemberMetadata.deserializer) { - revivedValue = objMemberMetadata.deserializer(objMemberValue); - } else if (objMemberMetadata.ctor) { - revivedValue = this.convertSingleValue( - objMemberValue, - { - selfConstructor: objMemberMetadata.ctor, - elementConstructor: objMemberMetadata.elementType, - keyConstructor: objMemberMetadata.keyType, - knownTypes: knownTypeConstructors - }, - objMemberDebugName, - objMemberOptions, - ); - } else { - throw new TypeError( - `Cannot deserialize ${objMemberDebugName} there is` - + ` no constructor nor deserialization function to use.`, - ); - } - - if (isValueDefined(revivedValue) - || (this.retrievePreserveNull(objMemberOptions) && revivedValue === null) - ) { - sourceObjectWithDeserializedProperties[objMemberMetadata.key] = revivedValue; - } - else if (objMemberMetadata.isRequired) - { - this._errorHandler(new TypeError(`Missing required member '${objMemberDebugName}'.`)); - } - }); - - // Next, instantiate target object. - let targetObject: IndexedObject; - - if (typeof sourceObjectMetadata.initializerCallback === "function") - { - try - { - targetObject = sourceObjectMetadata.initializerCallback( - sourceObjectWithDeserializedProperties, - 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); - - // Call onDeserialized method (if any). - if (sourceObjectMetadata.onDeserializedMethodName) - { - // check for member first - if (typeof (targetObject as any)[sourceObjectMetadata.onDeserializedMethodName] === "function") - { - (targetObject as any)[sourceObjectMetadata.onDeserializedMethodName](); - } - // check for static - else if (typeof (targetObject.constructor as any)[sourceObjectMetadata.onDeserializedMethodName] === "function") - { - (targetObject.constructor as any)[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. - let targetObject = {} as IndexedObject; - - Object.keys(sourceObject).forEach(sourceKey => - { - targetObject[sourceKey] = this.convertSingleValue(sourceObject[sourceKey], { - selfConstructor: sourceObject[sourceKey].constructor, - knownTypes: sourceObjectTypeInfo.knownTypes, - elementConstructor: sourceObjectTypeInfo.elementConstructor, - keyConstructor: sourceObjectTypeInfo.keyConstructor - }, sourceKey); - }); - - return targetObject; - } - } - - public convertSingleValue( - sourceObject: any, - typeInfo: IScopeTypeInfo, - memberName = "object", - memberOptions?: OptionsBase, - ) { - let expectedSelfType = typeInfo.selfConstructor; - let srcTypeNameForDebug = sourceObject ? nameof(sourceObject.constructor) : "undefined"; - - if (this.retrievePreserveNull(memberOptions) && sourceObject === null) - { - return null; - } - else if (!isValueDefined(sourceObject)) - { - return; - } - else if (isDirectlyDeserializableNativeType(expectedSelfType)) - { - if (sourceObject.constructor === expectedSelfType) - { - return sourceObject; - } - else - { - throw new TypeError(this._makeTypeErrorMessage(nameof(expectedSelfType), sourceObject.constructor, 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 as any); - else - this._throwTypeMismatchError("Date", "an ISO-8601 string", srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === Float32Array || expectedSelfType === Float64Array) - { - // Deserialize Float Array from number[]. - return this._convertAsFloatArray( - sourceObject, - expectedSelfType as any, - srcTypeNameForDebug, - memberName, - ); - } - else if ( - expectedSelfType === Uint8Array - || expectedSelfType === Uint8ClampedArray - || expectedSelfType === Uint16Array - || expectedSelfType === Uint32Array - ) { - // Deserialize Uint array from number[]. - return this._convertAsUintArray( - sourceObject, - expectedSelfType as any, - 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 (Array.isArray(sourceObject)) - return this.convertAsArray(sourceObject, typeInfo, memberName, memberOptions); - else - throw new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)); - } - else if (expectedSelfType === Set) - { - if (Array.isArray(sourceObject)) - return this.convertAsSet(sourceObject, typeInfo, memberName, memberOptions); - else - this._throwTypeMismatchError("Set", "Array", srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === Map) - { - if (Array.isArray(sourceObject)) - return this.convertAsMap(sourceObject, typeInfo, memberName, memberOptions); - 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, memberOptions); - } - } - - public convertAsArray( - sourceObject: any, - typeInfo: IScopeTypeInfo, - memberName = "object", - memberOptions?: OptionsBase, - ): any[] { - if (!(Array.isArray(sourceObject))) - { - 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 []; - } - - let elementTypeInfo: IScopeTypeInfo = { - selfConstructor: typeInfo.elementConstructor[0], - elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [], - knownTypes: typeInfo.knownTypes - }; - - return sourceObject.map(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, `${memberName}[]`, memberOptions); - } - 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; - } - }); - } - - public convertAsSet( - sourceObject: any, - typeInfo: IScopeTypeInfo, - memberName = "object", - memberOptions?: OptionsBase, - ): Set { - if (!(Array.isArray(sourceObject))) - { - 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(); - } - - let elementTypeInfo: IScopeTypeInfo = { - selfConstructor: typeInfo.elementConstructor[0], - elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [], - knownTypes: typeInfo.knownTypes - }; - let resultSet = new Set(); - - sourceObject.forEach((element, i) => - { - try - { - resultSet.add(this.convertSingleValue( - element, - elementTypeInfo, - `${memberName}[${i}]`, - memberOptions, - )); - } - 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; - } - - public convertAsMap( - sourceObject: any, - typeInfo: IScopeTypeInfo, - memberName = "object", - memberOptions?: OptionsBase, - ): Map { - if (!(Array.isArray(sourceObject))) - 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(); - } - - let keyTypeInfo: IScopeTypeInfo = { - selfConstructor: typeInfo.keyConstructor, - knownTypes: typeInfo.knownTypes - }; - - let valueTypeInfo: IScopeTypeInfo = { - selfConstructor: typeInfo.elementConstructor[0], - elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [], - knownTypes: typeInfo.knownTypes - }; - - let resultMap = new Map(); - - sourceObject.forEach((element: any) => - { - try - { - let key = this.convertSingleValue(element.key, keyTypeInfo, memberName, memberOptions); - - // Undefined/null keys not supported, skip if so. - if (isValueDefined(key)) - { - resultMap.set( - key, - this.convertSingleValue( - element.value, - valueTypeInfo, - `${memberName}[${key}]`, - memberOptions, - ), - ); - } - } - catch (e) - { - // Faulty entries are skipped, because a Map is not ordered, - // and skipping an entry does not affect others. - this._errorHandler(e); - } - }); - - return resultMap; - } - - private _convertAsFloatArray( - sourceObject: any, - arrayType: Constructor, - srcTypeNameForDebug: string, - memberName: string, - ): T { - if (Array.isArray(sourceObject) && sourceObject.every(elem => !isNaN(elem))) - return new arrayType(sourceObject); - return this._throwTypeMismatchError( - arrayType.name, - "a numeric source array", - srcTypeNameForDebug, - memberName, - ); - } - - private _convertAsUintArray( - sourceObject: any, - arrayType: Constructor, - srcTypeNameForDebug: string, - memberName: string, - ): T { - if (Array.isArray(sourceObject) && sourceObject.every(elem => !isNaN(elem))) - return new arrayType(sourceObject.map(value => ~~value)); - return this._throwTypeMismatchError( - arrayType.name, - "a numeric source array", - srcTypeNameForDebug, - memberName, - ); - } - - private _throwTypeMismatchError( - targetType: string, - expectedSourceType: string, - actualSourceType: string, - memberName: string, - ): never { - throw new TypeError( - `Could not deserialize ${memberName} as ${targetType}:` - + ` expected ${expectedSourceType}, got ${actualSourceType}.`, - ); - } - - private _makeTypeErrorMessage(expectedType: Function | string, actualType: Function | string, memberName: string) - { - const expectedTypeName = (typeof expectedType === "function") ? nameof(expectedType) : expectedType; - const actualTypeName = (typeof actualType === "function") ? nameof(actualType) : actualType; - - return `Could not deserialize ${memberName}: expected '${expectedTypeName}', got '${actualTypeName}'.`; - } - - private _instantiateType(ctor: any) - { - return new ctor(); - } - - private _mergeKnownTypes(...knownTypeMaps: Array>) - { - let result = new Map(); - - knownTypeMaps.forEach(knownTypes => - { - knownTypes.forEach((ctor, name) => - { - if (this._nameResolver) - { - result.set(this._nameResolver(ctor), ctor); - } - else - { - result.set(name, ctor); - } - }); - }); - - return result; - } - - private _createKnownTypesMap(knowTypes: Set) - { - const map = new Map(); - - knowTypes.forEach(ctor => - { - if (this._nameResolver) - { - map.set(this._nameResolver(ctor), ctor); - } - else - { - const knownTypeMeta = JsonObjectMetadata.getFromConstructor(ctor); - const name = knownTypeMeta && knownTypeMeta.isExplicitlyMarked && knownTypeMeta.name - ? knownTypeMeta.name - : ctor.name; - map.set(name, ctor); - } - }); - - return map; - } - - private _stringToArrayBuffer(str: string) - { - let buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char - let bufView = new Uint16Array(buf); - - for (let i = 0, strLen = str.length; i < strLen; i++) - { - bufView[i] = str.charCodeAt(i); - } - - return buf; - } - - private _stringToDataView(str: string) - { - return new DataView(this._stringToArrayBuffer(str)); - } - - private retrievePreserveNull(memberOptions?: OptionsBase): boolean { - return getOptionValue('preserveNull', mergeOptions(this.options, memberOptions)); - } -} diff --git a/src/typedjson/helpers.ts b/src/typedjson/helpers.ts deleted file mode 100644 index 1f87936..0000000 --- a/src/typedjson/helpers.ts +++ /dev/null @@ -1,177 +0,0 @@ -declare abstract class Reflect -{ - public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any; -} - -export const METADATA_FIELD_KEY = "__typedJsonJsonObjectMetadataInformation__"; - -export const MISSING_REFLECT_CONF_MSG = 'Are you sure, that you have both "experimentalDecorators"' + - ' and "emitDecoratorMetadata" in your tsconfig.json?'; - -export function getDefaultValue(type: { new (): T }): T|undefined -{ - switch (type as any) - { - case Number: - return 0 as any; - - case String: - return "" as any; - - case Boolean: - return false as any; - - case Array: - return [] as any; - - default: - return undefined; - } -} - -/** - * Determines whether the specified type is a type that can be passed on "as-is" into `JSON.stringify`. - * Values of these types don't need special conversion. - * @param type The constructor of the type (wrapper constructor for primitive types, e.g. `Number` for `number`). - */ -export function isDirectlySerializableNativeType(type: Function): boolean -{ - return !!(~[Date, Number, String, Boolean].indexOf(type as any)); -} - -export function isDirectlyDeserializableNativeType(type: Function): boolean -{ - return !!(~[Number, String, Boolean].indexOf(type as any)); -} - -export function isTypeTypedArray(type: Function): boolean -{ - return !!(~[Float32Array, Float64Array, Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array] - .indexOf(type as any)); -} - -export function isPrimitiveValue(obj: any): boolean -{ - switch (typeof obj) - { - case "string": - case "number": - case "boolean": - return true; - default: - return (obj instanceof String || obj instanceof Number || obj instanceof Boolean); - } -} - -export function isObject(value: any): value is Object -{ - return typeof value === "object"; -} - -function shouldOmitParseString(jsonStr: string, expectedType: Function): boolean { - const expectsTypesSerializedAsStrings = expectedType === String - || expectedType === ArrayBuffer - || expectedType === DataView; - - const hasQuotes = jsonStr.length >= 2 && jsonStr[0] === '"' && jsonStr[jsonStr.length-1] === '"'; - const isInteger = /^\d+$/.test(jsonStr.trim()); - - return (expectsTypesSerializedAsStrings && !hasQuotes) || ((!hasQuotes && !isInteger) && expectedType === Date); -} - -export function parseToJSObject(json: any, expectedType: Function): Object { - if (typeof json !== 'string' || shouldOmitParseString(json, expectedType)) - { - return json; - } - return JSON.parse(json); -} - -/** - * Determines if 'A' is a sub-type of 'B' (or if 'A' equals 'B'). - * @param A The supposed derived type. - * @param B The supposed base type. - */ -export function isSubtypeOf(A: Function, B: Function) -{ - return A === B || A.prototype instanceof B; -} - -export function logError(message?: any, ...optionalParams: any[]) -{ - if (typeof console === "object" && typeof console.error === "function") - { - console.error(message, ...optionalParams); - } - else if (typeof console === "object" && typeof console.log === "function") - { - console.log(`ERROR: ${message}`, ...optionalParams); - } -} - -export function logMessage(message?: any, ...optionalParams: any[]) -{ - if (typeof console === "object" && typeof console.log === "function") - { - console.log(message, ...optionalParams); - } -} - -export function logWarning(message?: any, ...optionalParams: any[]) -{ - if (typeof console === "object" && typeof console.warn === "function") - { - console.warn(message, ...optionalParams); - } - else if (typeof console === "object" && typeof console.log === "function") - { - console.log(`WARNING: ${message}`, ...optionalParams); - } -} - -/** - * Checks if the value is considered defined (not undefined and not null). - * @param value - */ -export function isValueDefined(value: T): value is Exclude -{ - return !(typeof value === "undefined" || value === null); -} - -export function isInstanceOf(value: any, constructor: Function): boolean -{ - if (typeof value === "number") - { - return (constructor === Number); - } - else if (typeof value === "string") - { - return (constructor === String); - } - else if (typeof value === "boolean") - { - return (constructor === Boolean); - } - else if (isObject(value)) - { - return (value instanceof constructor); - } - - return false; -} - -export const isReflectMetadataSupported = - (typeof Reflect === "object" && typeof Reflect.getMetadata === "function"); - -/** - * Gets the name of a function. - * @param fn The function whose name to get. - */ -export function nameof(fn: Function & { name?: string }) -{ - if (typeof fn.name === "string") - { - return fn.name; - } - return "undefined"; -} diff --git a/src/typedjson/json-array-member.ts b/src/typedjson/json-array-member.ts deleted file mode 100644 index 0f356ed..0000000 --- a/src/typedjson/json-array-member.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { nameof, logError, isReflectMetadataSupported, MISSING_REFLECT_CONF_MSG } from "./helpers"; -import { injectMetadataInformation } from "./metadata"; -import { extractOptionBase, OptionsBase } from "./options-base"; - -declare abstract class Reflect -{ - public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any; -} - -export interface IJsonArrayMemberOptions extends OptionsBase -{ - /** When set, indicates that the member must be present when deserializing. */ - isRequired?: boolean; - - /** When set, an empty array is emitted if the property is undefined/uninitialized. */ - emitDefaultValue?: boolean; - - /** Sets array dimensions (e.g. 1 for 'number[]' or 2 for 'number[][]'). Defaults to 1. */ - dimensions?: number; - - /** When set, the key on the JSON that should be used instead of the class property name */ - name?: string; - - /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */ - deserializer?: (json: any) => any; - - /** When set, this serializer will be used to serialize the member. */ - serializer?: (value: any) => any; -} - -/** - * 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. - */ -export function jsonArrayMember(elementConstructor: Function, options: IJsonArrayMemberOptions = {}) -{ - return (target: Object, propKey: string | symbol) => - { - let 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; - } - - const 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. ${MISSING_REFLECT_CONF_MSG}`); - return; - } - - injectMetadataInformation(target, propKey, { - ctor: Array, - elementType: createArrayElementType(elementConstructor, dimensions), - emitDefaultValue: options.emitDefaultValue, - isRequired: options.isRequired, - options: extractOptionBase(options), - key: propKey.toString(), - name: options.name || propKey.toString(), - deserializer: options.deserializer, - serializer: options.serializer, - }); - }; -} - -function createArrayElementType(elementCtor: Function, dimensions: number) { - const elementTypes = new Array(dimensions).fill(Array, 0, -1); - elementTypes[dimensions-1] = elementCtor; - return elementTypes; -} diff --git a/src/typedjson/json-map-member.ts b/src/typedjson/json-map-member.ts deleted file mode 100644 index bf0d9e3..0000000 --- a/src/typedjson/json-map-member.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { nameof, logError, isReflectMetadataSupported, MISSING_REFLECT_CONF_MSG } from "./helpers"; -import { injectMetadataInformation } from "./metadata"; -import { extractOptionBase, OptionsBase } from "./options-base"; - -declare abstract class Reflect -{ - public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any; -} - -export interface IJsonMapMemberOptions extends OptionsBase -{ - /** When set, indicates that the member must be present when deserializing. */ - isRequired?: boolean; - - /** When set, a default value is emitted for each uninitialized json member. */ - emitDefaultValue?: boolean; - - /** When set, the key on the JSON that should be used instead of the class property name */ - name?: string; - - /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */ - deserializer?: (json: any) => any; - - /** When set, this serializer will be used to serialize the member. */ - serializer?: (value: any) => any; -} - -/** - * 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. - */ -export function jsonMapMember(keyConstructor: Function, valueConstructor: Function, options: IJsonMapMemberOptions = {}) -{ - return (target: Object, propKey: string | symbol) => - { - let 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. ${MISSING_REFLECT_CONF_MSG}`); - return; - } - - injectMetadataInformation(target, propKey, { - ctor: Map, - elementType: [valueConstructor], - keyType: keyConstructor, - emitDefaultValue: options.emitDefaultValue, - isRequired: options.isRequired, - options: extractOptionBase(options), - key: propKey.toString(), - name: options.name || propKey.toString(), - deserializer: options.deserializer, - serializer: options.serializer, - }); - }; -} diff --git a/src/typedjson/json-member.ts b/src/typedjson/json-member.ts deleted file mode 100644 index ab65a89..0000000 --- a/src/typedjson/json-member.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { - nameof, logError, isReflectMetadataSupported, isValueDefined, logWarning, isSubtypeOf, MISSING_REFLECT_CONF_MSG, -} from "./helpers"; -import { injectMetadataInformation } from "./metadata"; -import { extractOptionBase, OptionsBase } from "./options-base"; - -declare abstract class Reflect -{ - public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any; -} - -export interface IJsonMemberOptions extends OptionsBase -{ - /** - * Sets the constructor of the property. - * Optional with ReflectDecorators. - */ - constructor?: Function; - - /** When set, indicates that the member must be present when deserializing. */ - isRequired?: boolean; - - /** When set, a default value is emitted if the property is uninitialized/undefined. */ - emitDefaultValue?: boolean; - - /** When set, the key on the JSON that should be used instead of the class property name. */ - name?: string; - - /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */ - deserializer?: (json: any) => any; - - /** When set, this serializer will be used to serialize the member. */ - serializer?: (value: any) => any; -} - -/** - * Specifies that a property is part of the object when serializing, with additional options. - * Omitting the 'constructor' option requires ReflectDecorators and that the property type is always explicitly declared. - * @param options Additional options. - */ -export function jsonMember(options: IJsonMemberOptions): PropertyDecorator; - -/** - * Specifies that a property is part of the object when serializing. - * This call signature requires ReflectDecorators and that the property type is always explicitly declared. - */ -export function jsonMember(target: Object, propertyKey: string | symbol): void; - -export function jsonMember(optionsOrTarget?: IJsonMemberOptions | Object, propKey?: string | symbol): PropertyDecorator | void -{ - if (optionsOrTarget instanceof Object && (typeof propKey === "string" || typeof propKey === "symbol")) - { - const target = optionsOrTarget as Object; - // For error messages. - const 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) - { - const reflectPropCtor = Reflect.getMetadata("design:type", target, propKey) as Function; - - if (!reflectPropCtor) - { - logError(`${decoratorName}: could not resolve detected property constructor at runtime. ${MISSING_REFLECT_CONF_MSG}`); - 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; - } - } - else - { - // jsonMember used as a decorator factory. - return (target: Object, _propKey: string | symbol) => - { - let options: IJsonMemberOptions = optionsOrTarget || {}; - let propCtor: Function|undefined; - let 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) as Function; - - 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, - isRequired: options.isRequired, - options: extractOptionBase(options), - key: _propKey.toString(), - name: options.name || _propKey.toString(), - deserializer: options.deserializer, - serializer: options.serializer, - }); - }; - } -} - -function isSpecialPropertyType(decoratorName: string, propCtor?: Function) -{ - 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; -} diff --git a/src/typedjson/json-set-member.ts b/src/typedjson/json-set-member.ts deleted file mode 100644 index e808e4b..0000000 --- a/src/typedjson/json-set-member.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { isReflectMetadataSupported, logError, MISSING_REFLECT_CONF_MSG, nameof } from "./helpers"; -import { injectMetadataInformation } from "./metadata"; -import { extractOptionBase, OptionsBase } from "./options-base"; - -declare abstract class Reflect -{ - public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any; -} - -export interface IJsonSetMemberOptions extends OptionsBase -{ - /** When set, indicates that the member must be present when deserializing. */ - isRequired?: boolean; - - /** When set, a default value is emitted for each uninitialized json member. */ - emitDefaultValue?: boolean; - - /** When set, the key on the JSON that should be used instead of the class property name */ - name?: string; - - /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */ - deserializer?: (json: any) => any; - - /** When set, this serializer will be used to serialize the member. */ - serializer?: (value: any) => any; -} - -/** - * 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. - */ -export function jsonSetMember(elementConstructor: Function, options: IJsonSetMemberOptions = {}) -{ - return (target: Object, propKey: string | symbol) => - { - const 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. ${MISSING_REFLECT_CONF_MSG}`); - return; - } - - injectMetadataInformation(target, propKey, { - ctor: Set, - elementType: [elementConstructor], - emitDefaultValue: options.emitDefaultValue, - isRequired: options.isRequired, - options: extractOptionBase(options), - key: propKey.toString(), - name: options.name || propKey.toString(), - deserializer: options.deserializer, - serializer: options.serializer, - }); - }; -} diff --git a/src/typedjson/metadata.ts b/src/typedjson/metadata.ts deleted file mode 100644 index f0d15b0..0000000 --- a/src/typedjson/metadata.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { nameof, logError, METADATA_FIELD_KEY, isDirectlySerializableNativeType, isTypeTypedArray } from "./helpers"; -import { IndexedObject } from "./types"; -import { OptionsBase } from "./options-base"; - -export interface JsonMemberMetadata -{ - /** If set, a default value will be emitted for uninitialized members. */ - emitDefaultValue?: boolean; - - /** Member name as it appears in the serialized JSON. */ - name: string; - - /** Property or field key of the json member. */ - key: string; - - /** Constuctor (type) reference of the member. */ - ctor?: Function; - - /** If set, indicates that the member must be present when deserializing. */ - isRequired?: boolean; - - options?: OptionsBase; - - /** If the json member is an array, map or set, sets member options of elements/values. Subsequent values define the types of nested arrays. */ - elementType?: Function[]; - - /** If the json member is a map, sets member options of array keys. */ - keyType?: Function; - - /** Custom deserializer to use. */ - deserializer?: (json: any) => any; - - /** Custom serializer to use. */ - serializer?: (value: any) => any; -} - -export class JsonObjectMetadata -{ - //#region Static - /** - * Gets the name of a class as it appears in a serialized JSON string. - * @param ctor The constructor of a class (with or without jsonObject). - */ - public static getJsonObjectName(ctor: Function): string - { - const metadata = JsonObjectMetadata.getFromConstructor(ctor); - return metadata ? nameof(metadata.classType) : nameof(ctor); - } - - /** - * Gets jsonObject metadata information from a class. - * @param ctor The constructor class. - */ - public static getFromConstructor(ctor: Function): JsonObjectMetadata|undefined - { - const prototype = ctor.prototype; - if (!prototype) - { - return; - } - - let metadata: JsonObjectMetadata|undefined; - if (prototype.hasOwnProperty(METADATA_FIELD_KEY)) - { - // The class prototype contains own jsonObject metadata - metadata = prototype[METADATA_FIELD_KEY]; - } - - // Ignore implicitly added jsonObject (through jsonMember) - if (metadata && metadata.isExplicitlyMarked) - { - return metadata; - } - - // In the end maybe it is something which we can handle directly - if (JsonObjectMetadata.doesHandleWithoutAnnotation(ctor)) - { - const primitiveMeta = new JsonObjectMetadata(ctor); - primitiveMeta.isExplicitlyMarked = true; - // we do not store the metadata here to not modify builtin prototype - return primitiveMeta; - } - } - - /** - * Gets the known type name of a jsonObject class for type hint. - * @param constructor The constructor class. - */ - public static getKnownTypeNameFromType(constructor: Function): string - { - const metadata = JsonObjectMetadata.getFromConstructor(constructor); - return metadata ? nameof(metadata.classType) : nameof(constructor); - } - - private static doesHandleWithoutAnnotation(ctor: Function): boolean - { - return isDirectlySerializableNativeType(ctor) || isTypeTypedArray(ctor) - || ctor === DataView || ctor === ArrayBuffer; - } - //#endregion - - constructor( - classType: Function, - ) { - this.classType = classType; - } - - public dataMembers: Map = new Map(); - - public knownTypes: Set = new Set(); - - public knownTypeMethodName?: string; - - /** Gets or sets the constructor function for the jsonObject. */ - public classType: Function; - - /** - * Indicates whether this class was explicitly annotated with @jsonObject - * or implicitly by @jsonMember - */ - public isExplicitlyMarked: boolean = false; - - /** - * Indicates whether this type is handled without annotation. This is usually - * used for the builtin types (except for Maps, Sets, and normal Arrays). - */ - public isHandledWithoutAnnotation: boolean = false; - - /** Name used to encode polymorphic type */ - public name?: string; - - public options?: OptionsBase; - - public onDeserializedMethodName?: string; - - public beforeSerializationMethodName?: string; - - public initializerCallback?: (sourceObject: Object, rawSourceObject: Object) => Object; -} - -export function injectMetadataInformation(constructor: IndexedObject, propKey: string | symbol, metadata: JsonMemberMetadata) -{ - const decoratorName = `@jsonMember on ${nameof(constructor.constructor)}.${String(propKey)}`; // For error messages. - let objectMetadata: JsonObjectMetadata; - - // When a property decorator is applied to a static member, 'constructor' is a constructor function. - // See: https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md#property-decorators - // ... and static members are not supported here, so abort. - if (typeof constructor === "function") - { - logError(`${decoratorName}: cannot use a static property.`); - return; - } - - // Methods cannot be serialized. - // @ts-ignore symbol indexing is not supported by ts - if (typeof constructor[propKey] === "function") - { - logError(`${decoratorName}: cannot use a method property.`); - return; - } - - if (!metadata || (!metadata.ctor && !metadata.deserializer)) - { - logError(`${decoratorName}: JsonMemberMetadata has unknown ctor.`); - return; - } - - // Add jsonObject metadata to 'constructor' if not yet exists ('constructor' is the prototype). - // NOTE: this will not fire up custom serialization, as 'constructor' must be explicitly marked with '@jsonObject' as well. - if (!constructor.hasOwnProperty(METADATA_FIELD_KEY)) - { - // No *own* metadata, create new. - objectMetadata = new JsonObjectMetadata(constructor.constructor); - - // Inherit @JsonMembers from parent @jsonObject (if any). - const parentMetadata: JsonObjectMetadata = constructor[METADATA_FIELD_KEY]; - if (parentMetadata) // && !constructor.hasOwnProperty(Helpers.METADATA_FIELD_KEY) - { - parentMetadata.dataMembers.forEach((_metadata, _propKey) => objectMetadata.dataMembers.set(_propKey, _metadata)); - } - - // ('constructor' is the prototype of the involved class, metadata information is added to this class prototype). - Object.defineProperty(constructor, METADATA_FIELD_KEY, { - enumerable: false, - configurable: false, - writable: false, - value: objectMetadata - }); - } - else - { - // JsonObjectMetadata already exists on 'constructor'. - objectMetadata = constructor[METADATA_FIELD_KEY]; - } - - if (!metadata.deserializer) - { - // @ts-ignore above is a check (!deser && !ctor) - objectMetadata.knownTypes.add(metadata.ctor); - } - - if (metadata.keyType) - objectMetadata.knownTypes.add(metadata.keyType); - - if (metadata.elementType) - metadata.elementType.forEach(elemCtor => objectMetadata.knownTypes.add(elemCtor)); - - // clear metadata of undefined properties to save memory - (Object.keys(metadata) as [keyof JsonMemberMetadata]) - .forEach((key) => (metadata[key] === undefined) && delete metadata[key]); - objectMetadata.dataMembers.set(metadata.name, metadata); -} diff --git a/src/typedjson/serializer.ts b/src/typedjson/serializer.ts deleted file mode 100644 index 5ccb41e..0000000 --- a/src/typedjson/serializer.ts +++ /dev/null @@ -1,463 +0,0 @@ -import { - isDirectlySerializableNativeType, - isInstanceOf, - isTypeTypedArray, - isValueDefined, - logError, - nameof, -} from "./helpers"; -import { IndexedObject } from "./types"; -import { JsonObjectMetadata } from "./metadata"; -import { getOptionValue, mergeOptions, OptionsBase } from "./options-base"; - -export interface IScopeTypeInfo -{ - selfType: Function; - elementTypes?: Function[]; - keyType?: Function; -} - -export interface IScopeArrayTypeInfo extends IScopeTypeInfo -{ - selfType: new () => Array; - elementTypes: Function[]; -} - -function isArrayTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeArrayTypeInfo { - return typeInfo.selfType === Array; -} - -export interface IScopeSetTypeInfo extends IScopeTypeInfo -{ - selfType: new () => Set; - elementTypes: [Function]; -} - -function isSetTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeSetTypeInfo { - return typeInfo.selfType === Set; -} - -export interface IScopeMapTypeInfo extends IScopeTypeInfo -{ - selfType: new () => Map; - elementTypes: [Function]; - keyType: Function; -} - -function isMapTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeMapTypeInfo { - return typeInfo.selfType === Map; -} - -export type TypeHintEmitter - = ( - targetObject: IndexedObject, - sourceObject: IndexedObject, - expectedSourceType: Function, - sourceTypeMetadata?: JsonObjectMetadata, - ) => void; - -function defaultTypeEmitter( - targetObject: IndexedObject, - sourceObject: IndexedObject, - expectedSourceType: Function, - sourceTypeMetadata?: JsonObjectMetadata, -) { - // 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) - { - targetObject.__type = sourceTypeMetadata && sourceTypeMetadata.name - ? sourceTypeMetadata.name - : nameof(sourceObject.constructor); - } -} - -/** - * 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 - */ -export class Serializer -{ - public options?: OptionsBase; - private _typeHintEmitter: TypeHintEmitter = defaultTypeEmitter; - private _errorHandler: (error: Error) => void = logError; - - public setTypeHintEmitter(typeEmitterCallback: TypeHintEmitter) - { - if (typeof typeEmitterCallback !== "function") - { - throw new TypeError("'typeEmitterCallback' is not a function."); - } - - this._typeHintEmitter = typeEmitterCallback; - } - - public setErrorHandler(errorHandlerCallback: (error: Error) => void) - { - 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. - */ - public convertSingleValue( - sourceObject: any, - typeInfo: IScopeTypeInfo, - memberName: string = "object", - memberOptions?: OptionsBase, - ): any { - if (this.retrievePreserveNull(memberOptions) && sourceObject === null) return null; - if (!isValueDefined(sourceObject)) return; - - if (!isInstanceOf(sourceObject, typeInfo.selfType)) - { - let expectedName = nameof(typeInfo.selfType); - let 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, memberOptions); - } - else if (isSetTypeInfo(typeInfo)) - { - return this.convertAsSet(sourceObject, typeInfo.elementTypes[0], memberName, memberOptions); - } - else if (isMapTypeInfo(typeInfo)) - { - return this.convertAsMap(sourceObject, typeInfo.keyType, typeInfo.elementTypes[0], memberName, memberOptions); - } - else if (isTypeTypedArray(typeInfo.selfType)) - { - return this.convertAsTypedArray(sourceObject); - } - else if (typeof sourceObject === "object") - { - return this.convertAsObject(sourceObject, typeInfo, memberName, memberOptions); - } - } - - /** - * Performs the conversion of a typed object (usually a class instance) to a simple - * javascript object for serialization. - */ - public convertAsObject( - sourceObject: IndexedObject, - typeInfo: IScopeTypeInfo, - memberName?: string, - memberOptions?: OptionsBase, - ) { - let sourceTypeMetadata: JsonObjectMetadata|undefined; - let targetObject: IndexedObject; - - 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 = JsonObjectMetadata.getFromConstructor(sourceObject.constructor); - } - else - { - sourceTypeMetadata = JsonObjectMetadata.getFromConstructor(typeInfo.selfType); - } - - if (sourceTypeMetadata) - { - - if (sourceTypeMetadata.beforeSerializationMethodName) { - // check for member first - if (typeof (sourceObject as any)[sourceTypeMetadata.beforeSerializationMethodName] === "function") - { - (sourceObject as any)[sourceTypeMetadata.beforeSerializationMethodName](); - } - // check for static - else if (typeof (sourceObject.constructor as any)[sourceTypeMetadata.beforeSerializationMethodName] === "function") - { - (sourceObject.constructor as any)[sourceTypeMetadata.beforeSerializationMethodName](); - } - else - { - this._errorHandler(new TypeError( - `beforeSerialization callback '${nameof(sourceTypeMetadata.classType)}.${sourceTypeMetadata.beforeSerializationMethodName}' is not a method.` - )); - } - } - - const sourceMeta = 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 = {}; - - const classOptions = mergeOptions(this.options, sourceMeta.options); - - sourceMeta.dataMembers.forEach((objMemberMetadata) => - { - const objMemberOptions = mergeOptions(classOptions, objMemberMetadata.options); - let serialized; - if (objMemberMetadata.serializer) { - serialized = objMemberMetadata.serializer(sourceObject[objMemberMetadata.key]); - } else if (objMemberMetadata.ctor) { - serialized = this.convertSingleValue( - sourceObject[objMemberMetadata.key], - { - selfType: objMemberMetadata.ctor, - elementTypes: objMemberMetadata.elementType, - keyType: objMemberMetadata.keyType, - }, - `${nameof(sourceMeta.classType)}.${objMemberMetadata.key}`, - objMemberOptions, - ); - } else { - throw new TypeError( - `Could not serialize ${objMemberMetadata.name}, there is` - + ` no constructor nor serialization function to use.`, - ); - } - - if (isValueDefined(serialized) - || (this.retrievePreserveNull(objMemberOptions) && serialized === null) - ) { - targetObject[objMemberMetadata.name] = serialized; - } - }); - } - 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 = { ...sourceObject }; - } - - // Add type-hint. - this._typeHintEmitter(targetObject, sourceObject, typeInfo.selfType, sourceTypeMetadata); - - return targetObject; - } - - /** - * 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. - * @param memberOptions If converted as a member, the member options. - */ - public convertAsArray( - sourceObject: any[], - expectedElementType: Function[], - memberName = "object", - memberOptions?: OptionsBase, - ): any[] { - 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((element, i) => - { - if (!(this.retrievePreserveNull(memberOptions) && element === null) - && !isInstanceOf(element, expectedElementType[0]) - ) { - const expectedTypeName = nameof(expectedElementType[0]); - const actualTypeName = element && nameof(element.constructor); - throw new TypeError(`Could not serialize ${memberName}[${i}]:` + - ` expected '${expectedTypeName}', got '${actualTypeName}'.`); - } - }); - - const typeInfoForElements: IScopeTypeInfo = { - selfType: expectedElementType[0], - // For multidimensional arrays. - elementTypes: expectedElementType.length > 1 ? expectedElementType.slice(1) : [], - }; - - if (memberName) - { - // Just for debugging purposes. - memberName += "[]"; - } - - return sourceObject.map( - element => this.convertSingleValue( - element, typeInfoForElements, memberName, memberOptions - ), - ); - } - - /** - * 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. - * @param memberOptions If converted as a member, the member options. - * @returns - */ - public convertAsSet( - sourceObject: Set, - expectedElementType: Function, - memberName = "object", - memberOptions?: OptionsBase, - ): any[] { - if (!expectedElementType) - throw new TypeError(`Could not serialize ${memberName} as Set: missing element type definition.`); - - let elementTypeInfo: IScopeTypeInfo = { - selfType: expectedElementType, - }; - - // For debugging and error tracking. - if (memberName) memberName += "[]"; - - let resultArray: any[] = []; - - // 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(element => - { - let resultElement = this.convertSingleValue(element, elementTypeInfo, memberName, memberOptions); - - // 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; - } - - /** - * 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. - * @param memberOptions If converted as a member, the member options. - */ - public convertAsMap( - sourceObject: Map, - expectedKeyType: Function, - expectedElementType: Function, - memberName = "object", - memberOptions?: OptionsBase, - ): Array<{ key: any, value: any }> { - 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.`); - - let elementTypeInfo: IScopeTypeInfo = { - selfType: expectedElementType, - elementTypes: [expectedElementType] - }; - - let keyTypeInfo: IScopeTypeInfo = { - selfType: expectedKeyType - }; - - if (memberName) memberName += "[]"; - - const resultArray: Array<{ key: any, value: any }> = []; - const preserveNull = this.retrievePreserveNull(memberOptions); - - // Convert each *entry* in the map to a simple javascript object with key and value properties. - sourceObject.forEach((value, key) => - { - let resultKeyValuePairObj = { - key: this.convertSingleValue(key, keyTypeInfo, memberName, memberOptions), - value: this.convertSingleValue(value, elementTypeInfo, memberName, memberOptions), - }; - - // We are not going to emit entries with undefined keys OR undefined values. - const keyDefined = isValueDefined(resultKeyValuePairObj.key); - const valueDefined = isValueDefined(resultKeyValuePairObj.value) - || (resultKeyValuePairObj.value === null && preserveNull); - if (keyDefined && valueDefined) - { - resultArray.push(resultKeyValuePairObj); - } - }); - - 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 - */ - public convertAsTypedArray(sourceObject: ArrayBufferView) - { - return Array.from(sourceObject as any); - } - - /** - * Performs the conversion of a raw ArrayBuffer to a string. - */ - public convertAsArrayBuffer(buffer: ArrayBuffer) - { - // ArrayBuffer -> 16-bit character codes -> character array -> joined string. - return Array.from(new Uint16Array(buffer)).map(charCode => String.fromCharCode(charCode)).join(""); - } - - /** - * Performs the conversion of DataView, converting its internal ArrayBuffer to a string and - * returning that string. - */ - public convertAsDataView(dataView: DataView) - { - return this.convertAsArrayBuffer(dataView.buffer); - } - - private retrievePreserveNull(memberOptions?: OptionsBase): boolean { - return getOptionValue('preserveNull', mergeOptions(this.options, memberOptions)); - } -} diff --git a/src/typedjson/types.ts b/src/typedjson/types.ts deleted file mode 100644 index eafe8ed..0000000 --- a/src/typedjson/types.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type IndexedObject = Object & { [key: string]: any }; -export type Constructor = new (...args: any[]) => T; -export type ParameterlessConstructor = new () => T; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..5913901 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,8 @@ +export type IndexedObject = Object & {[key: string]: any}; + +export interface AbstractType extends Function { + prototype: T; +} + +export type Constructor = new (...args: Array) => T; +export type Serializable = Constructor | AbstractType; diff --git a/tsconfig.json b/tsconfig.json index 6f449b7..5abef11 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,18 @@ -{ - "compilerOptions": { - "target": "ES5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ - "lib": ["es7", "dom"], - "module": "es2015", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - "sourceMap": true, /* Generates corresponding '.map' file. */ - "strict": true, - "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ +/* + This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScript’s language + server to improve development experience. It is not intended to be used to perform a compilation. - "outDir": "js" - }, - "files": [ - "src/typedjson.ts" + To learn more about this file see: + https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/#solution-style-tsconfig. +*/ +{ + "files": [], + "references": [ + { + "path": "./tsconfig/tsconfig.app.json" + }, + { + "path": "./tsconfig/tsconfig.spec.json" + } ] } diff --git a/tsconfig/README.md b/tsconfig/README.md new file mode 100644 index 0000000..7e7fb4b --- /dev/null +++ b/tsconfig/README.md @@ -0,0 +1,39 @@ +# TypedJSON's tsconfig +**[../tsconfig.json](../tsconfig.json)** +Used by IDEs for languages services. + +**[tsconfig.app.json](tsconfig.app.json)** +Used by language services to interpret and check library source code. + +**[tsconfig.app-base.json](tsconfig.app-base.json)** +Governs all library source files. Used as base for production bundles and `tsconfig.app.json`. + +**[tsconfig.app-strict.json](tsconfig.app-strict.json)** +A more strict TypeScript configuration which might be annoying if used during development. + +**[tsconfig.base.json](tsconfig.base.json)** +tsconfig.json on which all other configs are based. Used to define settings across the whole +library. + +**[tsconfig.bundle.cjs.json](tsconfig.bundle.cjs.json)** +Production bundle. CommonJS module. Used by Node. `main` field in `package.json`. + +**[tsconfig.bundle.esm.json](tsconfig.bundle.esm.json)** +Production bundle. ECMAScript module with es2015 target. Used by bundlers. `es2015` field in +`package.json`. + +**[tsconfig.bundle.esm5.json](tsconfig.bundle.esm5.json)** +Production bundle. ECMAScript module with es5 target. Used by bundlers. `module` field in +`package.json`. + +**[tsconfig.bundle.types.json](tsconfig.bundle.types.json)** +Production bundle. Generates types. + +**[tsconfig.lint.json](tsconfig.lint.json)** +Used by eslint, see [.eslintrc.yaml](../.eslintrc.yaml). + +**[tsconfig.spec.json](tsconfig.spec.json)** +Governs all test files. + +**[tsconfig.spec-strict.json](tsconfig.spec-strict.json)** +A more strict TypeScript configuration which might be annoying if used during development. diff --git a/tsconfig/tsconfig.app-base.json b/tsconfig/tsconfig.app-base.json new file mode 100644 index 0000000..6df7b30 --- /dev/null +++ b/tsconfig/tsconfig.app-base.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.base.json", + "files": [ + "../src/index.ts" + ] +} diff --git a/tsconfig/tsconfig.app-strict.json b/tsconfig/tsconfig.app-strict.json new file mode 100644 index 0000000..dcf945b --- /dev/null +++ b/tsconfig/tsconfig.app-strict.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.app.json", + "compilerOptions": { + "noUnusedLocals": true + } +} diff --git a/tsconfig/tsconfig.app.json b/tsconfig/tsconfig.app.json new file mode 100644 index 0000000..dfee93a --- /dev/null +++ b/tsconfig/tsconfig.app.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.app-base.json", + "compilerOptions": { + "noEmit": true + } +} diff --git a/tsconfig/tsconfig.base.json b/tsconfig/tsconfig.base.json new file mode 100644 index 0000000..ede3f0d --- /dev/null +++ b/tsconfig/tsconfig.base.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "declaration": false, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ + "dom", + "es5", + "es2015" + ], + "module": "es2015", + "moduleResolution": "Node", + "removeComments": true, + "sourceMap": true, + "strict": true, + "target": "ES5" + } +} diff --git a/tsconfig/tsconfig.bundle.cjs.json b/tsconfig/tsconfig.bundle.cjs.json new file mode 100644 index 0000000..1a7288c --- /dev/null +++ b/tsconfig/tsconfig.bundle.cjs.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.app-base.json", + "compilerOptions": { + "module": "CommonJS", + "outDir": "../lib/cjs", + "target": "es5" + } +} diff --git a/tsconfig/tsconfig.bundle.esm.json b/tsconfig/tsconfig.bundle.esm.json new file mode 100644 index 0000000..76e3e31 --- /dev/null +++ b/tsconfig/tsconfig.bundle.esm.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.app-base.json", + "compilerOptions": { + "importHelpers": true, + "module": "es2020", + "outDir": "../lib/esm", + "target": "es2015" + } +} diff --git a/tsconfig/tsconfig.bundle.esm5.json b/tsconfig/tsconfig.bundle.esm5.json new file mode 100644 index 0000000..803cb41 --- /dev/null +++ b/tsconfig/tsconfig.bundle.esm5.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.app-base.json", + "compilerOptions": { + "importHelpers": true, + "module": "es2020", + "outDir": "../lib/esm5", + "target": "es5" + } +} diff --git a/tsconfig/tsconfig.bundle.types.json b/tsconfig/tsconfig.bundle.types.json new file mode 100644 index 0000000..36efe08 --- /dev/null +++ b/tsconfig/tsconfig.bundle.types.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.bundle.esm.json", + "compilerOptions": { + "declaration": true, + "declarationDir": "../lib/types", + "declarationMap": true, + "emitDeclarationOnly": true, + "module": "es2015", + "removeComments": false, + "target": "es2020" + } +} diff --git a/tsconfig/tsconfig.lint.json b/tsconfig/tsconfig.lint.json new file mode 100644 index 0000000..9849113 --- /dev/null +++ b/tsconfig/tsconfig.lint.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.base.json", + "include": [ + "../spec/**/*.ts", + "../src/**/*.ts" + ] +} diff --git a/tsconfig/tsconfig.spec-strict.json b/tsconfig/tsconfig.spec-strict.json new file mode 100644 index 0000000..3db9ea8 --- /dev/null +++ b/tsconfig/tsconfig.spec-strict.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.spec.json", + "compilerOptions": { + "noUnusedLocals": true + } +} diff --git a/tsconfig/tsconfig.spec.json b/tsconfig/tsconfig.spec.json new file mode 100644 index 0000000..3051b86 --- /dev/null +++ b/tsconfig/tsconfig.spec.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "module": "CommonJS", + "noEmit": true, + "strict": false + }, + "include": [ + "../spec/**/*.ts" + ] +} diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 4f8a928..0000000 --- a/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -const path = require('path'); -const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); -const WebpackAutoInject = require('webpack-auto-inject-version'); - -module.exports = { - entry: { - 'typedjson': './src/typedjson.ts', - 'typedjson.min': './src/typedjson.ts', - }, - devtool: 'source-map', - module: { - rules: [ - { - test: /\.[jt]s$/, - use: 'ts-loader', - exclude: /node_modules/, - }, - ], - }, - resolve: { - extensions: [ '.ts', '.js' ], - }, - output: { - filename: '[name].js', - path: path.resolve(__dirname, 'js'), - library: 'typedjson', - libraryTarget: 'umd', - umdNamedDefine: true, - globalObject: `(typeof self !== 'undefined' ? self : this)`, - }, - optimization: { - minimizer: [ - new UglifyJsPlugin({ - include: /\.min\.js$/, - sourceMap: true, - }) - ], - }, - plugins: [ - new WebpackAutoInject({ - SHORT: 'typedjson', - components: { - AutoIncreaseVersion: false, - }, - componentsOptions: { - InjectAsComment: { - tag: 'Version: {version} - {date}', - dateFormat: 'isoDate', - }, - }, - }), - ], - mode: "production", -}; diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..8b9e612 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,5807 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.15.8": + version "7.15.8" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.15.8.tgz#45990c47adadb00c03677baa89221f7cc23d2503" + integrity sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg== + dependencies: + "@babel/highlight" "^7.14.5" + +"@babel/compat-data@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" + integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== + +"@babel/core@^7.7.5": + version "7.15.8" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.8.tgz#195b9f2bffe995d2c6c159e72fe525b4114e8c10" + integrity sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og== + dependencies: + "@babel/code-frame" "^7.15.8" + "@babel/generator" "^7.15.8" + "@babel/helper-compilation-targets" "^7.15.4" + "@babel/helper-module-transforms" "^7.15.8" + "@babel/helpers" "^7.15.4" + "@babel/parser" "^7.15.8" + "@babel/template" "^7.15.4" + "@babel/traverse" "^7.15.4" + "@babel/types" "^7.15.6" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + source-map "^0.5.0" + +"@babel/generator@^7.15.4", "@babel/generator@^7.15.8": + version "7.15.8" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.8.tgz#fa56be6b596952ceb231048cf84ee499a19c0cd1" + integrity sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g== + dependencies: + "@babel/types" "^7.15.6" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-compilation-targets@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz#cf6d94f30fbefc139123e27dd6b02f65aeedb7b9" + integrity sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ== + dependencies: + "@babel/compat-data" "^7.15.0" + "@babel/helper-validator-option" "^7.14.5" + browserslist "^4.16.6" + semver "^6.3.0" + +"@babel/helper-function-name@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc" + integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw== + dependencies: + "@babel/helper-get-function-arity" "^7.15.4" + "@babel/template" "^7.15.4" + "@babel/types" "^7.15.4" + +"@babel/helper-get-function-arity@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" + integrity sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA== + dependencies: + "@babel/types" "^7.15.4" + +"@babel/helper-hoist-variables@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df" + integrity sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA== + dependencies: + "@babel/types" "^7.15.4" + +"@babel/helper-member-expression-to-functions@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz#bfd34dc9bba9824a4658b0317ec2fd571a51e6ef" + integrity sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA== + dependencies: + "@babel/types" "^7.15.4" + +"@babel/helper-module-imports@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f" + integrity sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA== + dependencies: + "@babel/types" "^7.15.4" + +"@babel/helper-module-transforms@^7.15.8": + version "7.15.8" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz#d8c0e75a87a52e374a8f25f855174786a09498b2" + integrity sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg== + dependencies: + "@babel/helper-module-imports" "^7.15.4" + "@babel/helper-replace-supers" "^7.15.4" + "@babel/helper-simple-access" "^7.15.4" + "@babel/helper-split-export-declaration" "^7.15.4" + "@babel/helper-validator-identifier" "^7.15.7" + "@babel/template" "^7.15.4" + "@babel/traverse" "^7.15.4" + "@babel/types" "^7.15.6" + +"@babel/helper-optimise-call-expression@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz#f310a5121a3b9cc52d9ab19122bd729822dee171" + integrity sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw== + dependencies: + "@babel/types" "^7.15.4" + +"@babel/helper-replace-supers@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz#52a8ab26ba918c7f6dee28628b07071ac7b7347a" + integrity sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.15.4" + "@babel/helper-optimise-call-expression" "^7.15.4" + "@babel/traverse" "^7.15.4" + "@babel/types" "^7.15.4" + +"@babel/helper-simple-access@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz#ac368905abf1de8e9781434b635d8f8674bcc13b" + integrity sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg== + dependencies: + "@babel/types" "^7.15.4" + +"@babel/helper-split-export-declaration@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz#aecab92dcdbef6a10aa3b62ab204b085f776e257" + integrity sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw== + dependencies: + "@babel/types" "^7.15.4" + +"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.15.7": + version "7.15.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" + integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== + +"@babel/helper-validator-option@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" + integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== + +"@babel/helpers@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.15.4.tgz#5f40f02050a3027121a3cf48d497c05c555eaf43" + integrity sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ== + dependencies: + "@babel/template" "^7.15.4" + "@babel/traverse" "^7.15.4" + "@babel/types" "^7.15.4" + +"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" + integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.15.4", "@babel/parser@^7.15.8": + version "7.15.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.8.tgz#7bacdcbe71bdc3ff936d510c15dcea7cf0b99016" + integrity sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA== + +"@babel/template@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" + integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg== + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/parser" "^7.15.4" + "@babel/types" "^7.15.4" + +"@babel/traverse@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" + integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA== + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/generator" "^7.15.4" + "@babel/helper-function-name" "^7.15.4" + "@babel/helper-hoist-variables" "^7.15.4" + "@babel/helper-split-export-declaration" "^7.15.4" + "@babel/parser" "^7.15.4" + "@babel/types" "^7.15.4" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.15.4", "@babel/types@^7.15.6": + version "7.15.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" + integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig== + dependencies: + "@babel/helper-validator-identifier" "^7.14.9" + to-fast-properties "^2.0.0" + +"@eslint/eslintrc@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" + integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" + integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/nyc-config-typescript@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@istanbuljs/nyc-config-typescript/-/nyc-config-typescript-1.0.1.tgz#55172f5663b3635586add21b14d42ca94a163d58" + integrity sha512-/gz6LgVpky205LuoOfwEZmnUtaSmdk0QIMcNFj9OvxhiMhPpKftMgZmGN7jNj7jR+lr8IB1Yks3QSSSNSxfoaQ== + dependencies: + "@istanbuljs/schema" "^0.1.2" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@matthiaskunnen/eslint-config-base@^1.1.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@matthiaskunnen/eslint-config-base/-/eslint-config-base-1.2.1.tgz#b466d2fe5582435a30c3c89a0569fe152370c5d8" + integrity sha512-oTYX/Q6H5227RH0ehWTcSERs46Dx6W/9L8V4hMlhRR2fLeiCFhcxTazNlU9LJ+oYH7gKBvDy6EPq0JPKusGA9w== + dependencies: + eslint "^7.5.0" + eslint-plugin-import "^2.20.2" + eslint-plugin-unicorn "^19.0.1" + +"@matthiaskunnen/eslint-config-typescript@^1.2.0": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@matthiaskunnen/eslint-config-typescript/-/eslint-config-typescript-1.4.1.tgz#1f0ed5aa4e716ea1733464af1370d001253caf9c" + integrity sha512-6Sp2GG5vYBrJv35E1Ez2WXIhdHBzTaOY4eHTm8aeg4eYGydEjSxPTVR3WFsh6SG4Mr2SW7TtOyiyKqUp7n9ZNw== + dependencies: + "@matthiaskunnen/eslint-config-base" "^1.1.0" + "@typescript-eslint/eslint-plugin" "^2.31.0" + "@typescript-eslint/eslint-plugin-tslint" "^2.31.0" + "@typescript-eslint/parser" "^2.31.0" + tslint "^6.1.2" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@polka/url@^1.0.0-next.20": + version "1.0.0-next.21" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" + integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== + +"@size-limit/file@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@size-limit/file/-/file-4.12.0.tgz#50166eca7b9b5aa15f51a72b3d9d31e2d8530e6f" + integrity sha512-csgGSAG3s2y9eOl/taahojXY91AXpNgqLs9HJ5c/Qmrs+6UHgXbwJ4vo475NfZmt1Y9simircb1ygqupauNUyA== + dependencies: + semver "7.3.5" + +"@size-limit/preset-small-lib@^4.5.7": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@size-limit/preset-small-lib/-/preset-small-lib-4.12.0.tgz#0f7eb6ca7b7e6acb87b17bf6f7d9000946423cfc" + integrity sha512-jqUT2PiPN4Bf9aeUcTHt78+mELwo1x3K+w4grfNkzV/46j1rK3eXarls4qc0/FHolE76cLgNTLNjrX/Zb9c65w== + dependencies: + "@size-limit/file" "4.12.0" + "@size-limit/webpack" "4.12.0" + +"@size-limit/webpack@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@size-limit/webpack/-/webpack-4.12.0.tgz#65076310bbe4f043fad0a3af2bea0423573ff7ae" + integrity sha512-CtqSqxffexYmuAKeKAT2xcDmLwGChHXeq8Y9gjIe9vxfzUx1HU7Nmc0XyvsLGZG1qZO4TFuANlfQeavGY0jB6A== + dependencies: + css-loader "^5.2.6" + escape-string-regexp "^4.0.0" + file-loader "^6.2.0" + mkdirp "^1.0.4" + nanoid "^3.1.23" + optimize-css-assets-webpack-plugin "^6.0.0" + pnp-webpack-plugin "^1.6.4" + rimraf "^3.0.2" + style-loader "^2.0.0" + webpack "^4.44.1" + webpack-bundle-analyzer "^4.4.2" + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + +"@types/eslint-visitor-keys@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" + integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== + +"@types/jasmine@^3.5.3": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.9.1.tgz#94c65ee8bf9d24d9e1d84abaed57b6e0da8b49de" + integrity sha512-PVpjh8S8lqKFKurWSKdFATlfBHGPzgy0PoDdzQ+rr78jTQ0aacyh9YndzZcAUPxhk4kRujItFFGQdUJ7flHumw== + +"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.8": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + +"@types/normalize-package-data@^2.4.0": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" + integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@typescript-eslint/eslint-plugin-tslint@^2.31.0": + version "2.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin-tslint/-/eslint-plugin-tslint-2.34.0.tgz#0a2cea8e9a0726ae5a42cecd94095b41b749a8e7" + integrity sha512-sCPCbFm1qRTzloeMUlHEKfgQH/2u9bUcW7tX5wjzRw1LWzsr+iNXS8I+2or9ep8mlqqE0Vy6hsMm4vVF82M2jw== + dependencies: + "@typescript-eslint/experimental-utils" "2.34.0" + lodash "^4.17.15" + +"@typescript-eslint/eslint-plugin@^2.31.0": + version "2.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz#6f8ce8a46c7dea4a6f1d171d2bb8fbae6dac2be9" + integrity sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ== + dependencies: + "@typescript-eslint/experimental-utils" "2.34.0" + functional-red-black-tree "^1.0.1" + regexpp "^3.0.0" + tsutils "^3.17.1" + +"@typescript-eslint/experimental-utils@2.34.0": + version "2.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz#d3524b644cdb40eebceca67f8cf3e4cc9c8f980f" + integrity sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/typescript-estree" "2.34.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/parser@^2.31.0": + version "2.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.34.0.tgz#50252630ca319685420e9a39ca05fe185a256bc8" + integrity sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA== + dependencies: + "@types/eslint-visitor-keys" "^1.0.0" + "@typescript-eslint/experimental-utils" "2.34.0" + "@typescript-eslint/typescript-estree" "2.34.0" + eslint-visitor-keys "^1.1.0" + +"@typescript-eslint/typescript-estree@2.34.0": + version "2.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz#14aeb6353b39ef0732cc7f1b8285294937cf37d5" + integrity sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg== + dependencies: + debug "^4.1.1" + eslint-visitor-keys "^1.1.0" + glob "^7.1.6" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +acorn-jsx@^5.2.0, acorn-jsx@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn-walk@^8.0.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^6.4.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== + +acorn@^7.1.1, acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.0.4: + version "8.5.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" + integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.1: + version "8.6.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.3.tgz#11a66527761dc3e9a3845ea775d2d3c0414e8764" + integrity sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +alphanum-sort@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= + +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +append-transform@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-2.0.0.tgz#99d9d29c7b38391e6f428d28ce136551f0b77e12" + integrity sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg== + dependencies: + default-require-extensions "^3.0.0" + +aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-includes@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" + integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + get-intrinsic "^1.1.1" + is-string "^1.0.7" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +array.prototype.flat@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13" + integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.0.2, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bl@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.0.0, bn.js@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^4.0.0, browserslist@^4.16.0, browserslist@^4.16.6: + version "4.17.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.3.tgz#2844cd6eebe14d12384b0122d217550160d2d624" + integrity sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ== + dependencies: + caniuse-lite "^1.0.30001264" + electron-to-chromium "^1.3.857" + escalade "^3.1.1" + node-releases "^1.1.77" + picocolors "^0.2.1" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bytes-iec@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/bytes-iec/-/bytes-iec-3.1.1.tgz#94cd36bf95c2c22a82002c247df8772d1d591083" + integrity sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA== + +cacache@^12.0.2: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +caching-transform@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-4.0.0.tgz#00d297a4206d71e2163c39eaffa8157ac0651f0f" + integrity sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA== + dependencies: + hasha "^5.0.0" + make-dir "^3.0.0" + package-hash "^4.0.0" + write-file-atomic "^3.0.0" + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.0.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001264: + version "1.0.30001265" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz#0613c9e6c922e422792e6fcefdf9a3afeee4f8c3" + integrity sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw== + +chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0, chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chokidar@^3.4.1, chokidar@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +ci-job-number@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/ci-job-number/-/ci-job-number-1.2.2.tgz#f4e5918fcaeeda95b604f214be7d7d4a961fe0c0" + integrity sha512-CLOGsVDrVamzv8sXJGaILUVI6dsuAkouJP/n6t+OxLPeeA4DDby7zn9SB6EUpa1H7oIKoE+rMmkW80zYsFfUjA== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clean-regexp/-/clean-regexp-1.0.0.tgz#8df7c7aae51fd36874e8f8d05b9180bc11a3fed7" + integrity sha1-jffHquUf02h06PjQW5GAvBGj/tc= + dependencies: + escape-string-regexp "^1.0.5" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-spinners@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" + integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colord@^2.0.1, colord@^2.6: + version "2.8.0" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.8.0.tgz#64fb7aa03de7652b5a39eee50271a104c2783b12" + integrity sha512-kNkVV4KFta3TYQv0bzs4xNwLaeag261pxgzGQSh4cQ1rEhYjcTJfFRP0SDlbhLONg0eSoLzrDd79PosjbltufA== + +colorette@^1.2.2, colorette@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" + integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== + +commander@^2.12.1, commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +compare-versions@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" + integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cosmiconfig@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" + integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.0, cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-color-names@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-1.0.1.tgz#6ff7ee81a823ad46e020fa2fd6ab40a887e2ba67" + integrity sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA== + +css-declaration-sorter@^6.0.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.1.3.tgz#e9852e4cf940ba79f509d9425b137d1f94438dc2" + integrity sha512-SvjQjNRZgh4ULK1LDJ2AduPKUKxIqmtU7ZAyi47BTV+M90Qvxr9AB6lKlLbDUfXqI9IQeYA8LbAsCZPpJEV3aA== + dependencies: + timsort "^0.3.0" + +css-loader@^5.2.6: + version "5.2.7" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae" + integrity sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg== + dependencies: + icss-utils "^5.1.0" + loader-utils "^2.0.0" + postcss "^8.2.15" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^3.0.0" + semver "^7.3.5" + +css-select@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067" + integrity sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA== + dependencies: + boolbase "^1.0.0" + css-what "^5.0.0" + domhandler "^4.2.0" + domutils "^2.6.0" + nth-check "^2.0.0" + +css-tree@^1.1.2, css-tree@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + +css-what@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" + integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-default@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.4.tgz#359943bf00c5c8e05489f12dd25f3006f2c1cbd2" + integrity sha512-sPpQNDQBI3R/QsYxQvfB4mXeEcWuw0wGtKtmS5eg8wudyStYMgKOQT39G07EbW1LB56AOYrinRS9f0ig4Y3MhQ== + dependencies: + css-declaration-sorter "^6.0.3" + cssnano-utils "^2.0.1" + postcss-calc "^8.0.0" + postcss-colormin "^5.2.0" + postcss-convert-values "^5.0.1" + postcss-discard-comments "^5.0.1" + postcss-discard-duplicates "^5.0.1" + postcss-discard-empty "^5.0.1" + postcss-discard-overridden "^5.0.1" + postcss-merge-longhand "^5.0.2" + postcss-merge-rules "^5.0.2" + postcss-minify-font-values "^5.0.1" + postcss-minify-gradients "^5.0.2" + postcss-minify-params "^5.0.1" + postcss-minify-selectors "^5.1.0" + postcss-normalize-charset "^5.0.1" + postcss-normalize-display-values "^5.0.1" + postcss-normalize-positions "^5.0.1" + postcss-normalize-repeat-style "^5.0.1" + postcss-normalize-string "^5.0.1" + postcss-normalize-timing-functions "^5.0.1" + postcss-normalize-unicode "^5.0.1" + postcss-normalize-url "^5.0.2" + postcss-normalize-whitespace "^5.0.1" + postcss-ordered-values "^5.0.2" + postcss-reduce-initial "^5.0.1" + postcss-reduce-transforms "^5.0.1" + postcss-svgo "^5.0.2" + postcss-unique-selectors "^5.0.1" + +cssnano-utils@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-2.0.1.tgz#8660aa2b37ed869d2e2f22918196a9a8b6498ce2" + integrity sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ== + +cssnano@^5.0.2: + version "5.0.8" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.8.tgz#39ad166256980fcc64faa08c9bb18bb5789ecfa9" + integrity sha512-Lda7geZU0Yu+RZi2SGpjYuQz4HI4/1Y+BhdD0jL7NXAQ5larCzVn+PUGuZbDMYz904AXXCOgO5L1teSvgu7aFg== + dependencies: + cssnano-preset-default "^5.1.4" + is-resolvable "^1.1.0" + lilconfig "^2.0.3" + yaml "^1.10.2" + +csso@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= + +debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +default-require-extensions@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-3.0.0.tgz#e03f93aac9b2b6443fc52e5e4a37b3ad9ad8df96" + integrity sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg== + dependencies: + strip-bom "^4.0.0" + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-serializer@^1.0.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== + +domhandler@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.2.tgz#e825d721d19a86b8c201a35264e226c678ee755f" + integrity sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.6.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +duplexer@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +electron-to-chromium@^1.3.857: + version "1.3.867" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.867.tgz#7cb484db4b57c28da0b65c51e434c3a1f3f9aa0d" + integrity sha512-WbTXOv7hsLhjJyl7jBfDkioaY++iVVZomZ4dU6TMe/SzucV6mUAs2VZn/AehBwuZMiNEQDaPuTGn22YK5o+aDw== + +elliptic@^6.5.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +enquirer@^2.3.5, enquirer@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +errno@^0.1.3, errno@~0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.19.0, es-abstract@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.1" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" + object-inspect "^1.11.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es6-error@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" + integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-ast-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz#3d58ba557801cfb1c941d68131ee9f8c34bd1586" + integrity sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA== + dependencies: + lodash.get "^4.4.2" + lodash.zip "^4.2.0" + +eslint-import-resolver-node@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" + integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== + dependencies: + debug "^3.2.7" + resolve "^1.20.0" + +eslint-module-utils@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.0.tgz#9e97c12688113401259b39d960e6a1f09f966435" + integrity sha512-hqSE88MmHl3ru9SYvDyGrlo0JwROlf9fiEMplEV7j/EAuq9iSlIlyCFbBT6pdULQBSnBYtYKiMLps+hKkyP7Gg== + dependencies: + debug "^3.2.7" + find-up "^2.1.0" + pkg-dir "^2.0.0" + +eslint-plugin-import@^2.20.2: + version "2.25.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz#b3b9160efddb702fc1636659e71ba1d10adbe9e9" + integrity sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g== + dependencies: + array-includes "^3.1.4" + array.prototype.flat "^1.2.5" + debug "^2.6.9" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.6" + eslint-module-utils "^2.7.0" + has "^1.0.3" + is-core-module "^2.7.0" + is-glob "^4.0.3" + minimatch "^3.0.4" + object.values "^1.1.5" + resolve "^1.20.0" + tsconfig-paths "^3.11.0" + +eslint-plugin-jasmine@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-jasmine/-/eslint-plugin-jasmine-4.1.2.tgz#50cc20d603b02b37727f8d174d4b83b9b8ef25a5" + integrity sha512-Jr52EBi6Ql5WVDvRCKBID9kRD6/CaObvCWmgHpqobczX2Mzt8/QMu9vpgx6q/O5jyQ9CIGrKaEbPuEfHRf8guw== + +eslint-plugin-unicorn@^19.0.1: + version "19.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-19.0.1.tgz#05eef02f33426b8aa4f21cd5e4785b456335b85b" + integrity sha512-fu0/h5mHXfBC6EkA3i2vCjsfC8j53+T9txGhNL4fpxJ+1JKsUKfv+tmXDgy0XnLHhFjnOZp4tRWJWbcykeIP2Q== + dependencies: + ci-info "^2.0.0" + clean-regexp "^1.0.0" + eslint-ast-utils "^1.1.0" + eslint-template-visitor "^1.1.0" + eslint-utils "^2.0.0" + import-modules "^2.0.0" + lodash "^4.17.15" + read-pkg-up "^7.0.1" + regexp-tree "^0.1.21" + reserved-words "^0.1.2" + safe-regex "^2.1.1" + semver "^7.1.3" + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^5.0.0, eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-template-visitor@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-template-visitor/-/eslint-template-visitor-1.1.0.tgz#f090d124d1a52e05552149fc50468ed59608b166" + integrity sha512-Lmy6QVlmFiIGl5fPi+8ACnov3sare+0Ouf7deJAGGhmUfeWJ5fVarELUxZRpsZ9sHejiJUq8626d0dn9uvcZTw== + dependencies: + eslint-visitor-keys "^1.1.0" + espree "^6.1.1" + multimap "^1.0.2" + +eslint-utils@^2.0.0, eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint@^7.5.0: + version "7.32.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" + integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.3" + "@humanwhocodes/config-array" "^0.5.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.1.2" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.9" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^6.1.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" + integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== + dependencies: + acorn "^7.1.1" + acorn-jsx "^5.2.0" + eslint-visitor-keys "^1.1.0" + +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.1.0, esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +events@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.1.1: + version "3.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" + integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +file-loader@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-cache-dir@^3.2.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-versions@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-4.0.0.tgz#3c57e573bf97769b8cb8df16934b627915da4965" + integrity sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ== + dependencies: + semver-regex "^3.1.2" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561" + integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA== + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +foreground-child@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" + integrity sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^3.0.2" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fromentries@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.3.2.tgz#e4bca6808816bf8f93b52750f1127f5a6fd86e3a" + integrity sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg== + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^13.6.0, globals@^13.9.0: + version "13.11.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.11.0.tgz#40ef678da117fe7bd2e28f1fab24951bd0255be7" + integrity sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g== + dependencies: + type-fest "^0.20.2" + +globby@^11.0.3: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== + +gzip-size@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" + integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== + dependencies: + duplexer "^0.1.2" + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hasha@^5.0.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/hasha/-/hasha-5.2.2.tgz#a48477989b3b327aea3c04f53096d816d97522a1" + integrity sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ== + dependencies: + is-stream "^2.0.0" + type-fest "^0.8.0" + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +husky@^4.2.5: + version "4.3.8" + resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.8.tgz#31144060be963fd6850e5cc8f019a1dfe194296d" + integrity sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow== + dependencies: + chalk "^4.0.0" + ci-info "^2.0.0" + compare-versions "^3.6.0" + cosmiconfig "^7.0.0" + find-versions "^4.0.0" + opencollective-postinstall "^2.0.2" + pkg-dir "^5.0.0" + please-upgrade-node "^3.2.0" + slash "^3.0.0" + which-pm-runs "^1.0.0" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ieee754@^1.1.13, ieee754@^1.1.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-modules@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-modules/-/import-modules-2.1.0.tgz#abe7df297cb6c1f19b57246eb8b8bd9664b6d8c2" + integrity sha512-8HEWcnkbGpovH9yInoisxaSoIg9Brbul+Ju3Kqe2UsYDUBJD/iQjSgEj0zPcTDPKfPp2fs5xlv1i+JSye/m1/A== + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + +is-core-module@^2.2.0, is-core-module@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3" + integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ== + dependencies: + has "^1.0.3" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + +is-number-object@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + +is-resolvable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-weakref@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" + integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== + dependencies: + call-bind "^1.0.0" + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.0.0-alpha.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.2.tgz#36786d4d82aad2ea5911007e255e2da6b5f80d86" + integrity sha512-o5+eTUYzCJ11/+JhW5/FUCdfsdoYVdQ/8I/OveE2XsjehYn5DdeSnNQAbjYaO8gQ6hvGTN6GM6ddQqpTVG5j8g== + +istanbul-lib-hook@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz#8f84c9434888cc6b1d0a9d7092a76d239ebf0cc6" + integrity sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ== + dependencies: + append-transform "^2.0.0" + +istanbul-lib-instrument@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" + integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== + dependencies: + "@babel/core" "^7.7.5" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.0.0" + semver "^6.3.0" + +istanbul-lib-processinfo@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz#e1426514662244b2f25df728e8fd1ba35fe53b9c" + integrity sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw== + dependencies: + archy "^1.0.0" + cross-spawn "^7.0.0" + istanbul-lib-coverage "^3.0.0-alpha.1" + make-dir "^3.0.0" + p-map "^3.0.0" + rimraf "^3.0.0" + uuid "^3.3.3" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.4.tgz#5c38ce8136edf484c0fcfbf7514aafb0363ed1db" + integrity sha512-bFjUnc95rHjdCR63WMHUS7yfJJh8T9IPSWavvR02hhjVwezWALZ5axF9EqjmwZHpXqkzbgAMP8DmAtiyNxrdrQ== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jasmine-core@~3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.9.0.tgz#09a3c8169fe98ec69440476d04a0e4cb4d59e452" + integrity sha512-Tv3kVbPCGVrjsnHBZ38NsPU3sDOtNa0XmbG2baiyJqdb5/SPpDO6GVwJYtUryl6KB4q1Ssckwg612ES9Z0dreQ== + +jasmine@^3.5.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-3.9.0.tgz#286c4f9f88b69defc24acf3989af5533d5c6a0e6" + integrity sha512-JgtzteG7xnqZZ51fg7N2/wiQmXon09szkALcRMTgCMX4u/m17gVJFjObnvw5FXkZOWuweHPaPRVB6DI2uN0wVA== + dependencies: + glob "^7.1.6" + jasmine-core "~3.9.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +last-call-webpack-plugin@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555" + integrity sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w== + dependencies: + lodash "^4.17.5" + webpack-sources "^1.1.0" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lilconfig@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.3.tgz#68f3005e921dafbd2a2afb48379986aa6d2579fd" + integrity sha512-EHKqr/+ZvdKCifpNrJCKxBTgk5XupZA3y/aCPY9mxfgBzmgh93Mt/WqjjQ38oMxXuvDokaKiM3lAgvSH2sjtHg== + +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +lint-staged@^10.2.13: + version "10.5.4" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.5.4.tgz#cd153b5f0987d2371fc1d2847a409a2fe705b665" + integrity sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg== + dependencies: + chalk "^4.1.0" + cli-truncate "^2.1.0" + commander "^6.2.0" + cosmiconfig "^7.0.0" + debug "^4.2.0" + dedent "^0.7.0" + enquirer "^2.3.6" + execa "^4.1.0" + listr2 "^3.2.2" + log-symbols "^4.0.0" + micromatch "^4.0.2" + normalize-path "^3.0.0" + please-upgrade-node "^3.2.0" + string-argv "0.3.1" + stringify-object "^3.3.0" + +listr2@^3.2.2: + version "3.12.2" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.12.2.tgz#2d55cc627111603ad4768a9e87c9c7bb9b49997e" + integrity sha512-64xC2CJ/As/xgVI3wbhlPWVPx0wfTqbUAkpb7bjDi0thSWMqrf07UFhrfsGoo8YSXmF049Rp9C0cjLC8rZxK9A== + dependencies: + cli-truncate "^2.1.0" + colorette "^1.4.0" + log-update "^4.0.0" + p-map "^4.0.0" + rxjs "^6.6.7" + through "^2.3.8" + wrap-ansi "^7.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@^1.2.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +loader-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash.zip@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.zip/-/lodash.zip-4.2.0.tgz#ec6662e4896408ed4ab6c542a3990b72cc080020" + integrity sha1-7GZi5IlkCO1KtsVCo5kLcswIACA= + +lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.5: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@^4.0.0, log-symbols@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.0, make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + +memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime@^2.3.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" + integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.1, mkdirp@^0.5.3: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multimap@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multimap/-/multimap-1.1.0.tgz#5263febc085a1791c33b59bb3afc6a76a2a10ca8" + integrity sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw== + +nan@^2.12.1: + version "2.15.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" + integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== + +nanocolors@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/nanocolors/-/nanocolors-0.1.12.tgz#8577482c58cbd7b5bb1681db4cf48f11a87fd5f6" + integrity sha512-2nMHqg1x5PU+unxX7PGY7AuYxl2qDx7PSrTRjizr8sxdd3l/3hBuWWaki62qmtYm2U5i4Z5E7GbjlyDFhs9/EQ== + +nanoid@^3.1.23, nanoid@^3.1.28: + version "3.1.29" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.29.tgz#214fb2d7a33e1a5bef4757b779dfaeb6a4e5aeb4" + integrity sha512-dW2pUSGZ8ZnCFIlBIA31SV8huOGCHb6OwzVCc7A69rb/a+SgPBwfmLvK5TKQ3INPbRkcI8a/Owo0XbiTNH19wg== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +neo-async@^2.5.0, neo-async@^2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + +node-preload@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301" + integrity sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ== + dependencies: + process-on-spawn "^1.0.0" + +node-releases@^1.1.77: + version "1.1.77" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.77.tgz#50b0cfede855dd374e7585bf228ff34e57c1c32e" + integrity sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ== + +normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +npm-run-all@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" + integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== + dependencies: + ansi-styles "^3.2.1" + chalk "^2.4.1" + cross-spawn "^6.0.5" + memorystream "^0.3.1" + minimatch "^3.0.4" + pidtree "^0.3.0" + read-pkg "^3.0.0" + shell-quote "^1.6.1" + string.prototype.padend "^3.0.0" + +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nth-check@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" + integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== + dependencies: + boolbase "^1.0.0" + +nyc@^15.0.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-15.1.0.tgz#1335dae12ddc87b6e249d5a1994ca4bdaea75f02" + integrity sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A== + dependencies: + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + caching-transform "^4.0.0" + convert-source-map "^1.7.0" + decamelize "^1.2.0" + find-cache-dir "^3.2.0" + find-up "^4.1.0" + foreground-child "^2.0.0" + get-package-type "^0.1.0" + glob "^7.1.6" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-hook "^3.0.0" + istanbul-lib-instrument "^4.0.0" + istanbul-lib-processinfo "^2.0.2" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.0.2" + make-dir "^3.0.0" + node-preload "^0.2.1" + p-map "^3.0.0" + process-on-spawn "^1.0.0" + resolve-from "^5.0.0" + rimraf "^3.0.0" + signal-exit "^3.0.2" + spawn-wrap "^2.0.0" + test-exclude "^6.0.0" + yargs "^15.0.2" + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" + integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +object.values@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" + integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +opencollective-postinstall@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" + integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== + +opener@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" + integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== + +optimize-css-assets-webpack-plugin@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-6.0.1.tgz#7719bceabba1f3891ec3ae04efb81a1cc99cd793" + integrity sha512-BshV2UZPfggZLdUfN3zFBbG4sl/DynUI+YCB6fRRDWaqO2OiWN8GPcp4Y0/fEV6B3k9Hzyk3czve3V/8B/SzKQ== + dependencies: + cssnano "^5.0.2" + last-call-webpack-plugin "^3.0.0" + postcss "^8.2.1" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +ora@^5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" + integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== + dependencies: + bl "^4.1.0" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.5.0" + is-interactive "^1.0.0" + is-unicode-supported "^0.1.0" + log-symbols "^4.1.0" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" + integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== + dependencies: + aggregate-error "^3.0.0" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +package-hash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-4.0.0.tgz#3537f654665ec3cc38827387fc904c163c54f506" + integrity sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ== + dependencies: + graceful-fs "^4.1.15" + hasha "^5.0.0" + lodash.flattendeep "^4.4.0" + release-zalgo "^1.0.0" + +pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== + dependencies: + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pbkdf2@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +picocolors@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" + integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +pidtree@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" + integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + +please-upgrade-node@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" + integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== + dependencies: + semver-compare "^1.0.0" + +pnp-webpack-plugin@^1.6.4: + version "1.7.0" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz#65741384f6d8056f36e2255a8d67ffc20866f5c9" + integrity sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg== + dependencies: + ts-pnp "^1.1.6" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-calc@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.0.0.tgz#a05b87aacd132740a5db09462a3612453e5df90a" + integrity sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g== + dependencies: + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.2" + +postcss-colormin@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.2.0.tgz#2b620b88c0ff19683f3349f4cf9e24ebdafb2c88" + integrity sha512-+HC6GfWU3upe5/mqmxuqYZ9B2Wl4lcoUUNkoaX59nEWV4EtADCMiBqui111Bu8R8IvaZTmqmxrqOAqjbHIwXPw== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + colord "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-convert-values@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.1.tgz#4ec19d6016534e30e3102fdf414e753398645232" + integrity sha512-C3zR1Do2BkKkCgC0g3sF8TS0koF2G+mN8xxayZx3f10cIRmTaAnpgpRQZjNekTZxM2ciSPoh2IWJm0VZx8NoQg== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-discard-comments@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz#9eae4b747cf760d31f2447c27f0619d5718901fe" + integrity sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg== + +postcss-discard-duplicates@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz#68f7cc6458fe6bab2e46c9f55ae52869f680e66d" + integrity sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA== + +postcss-discard-empty@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz#ee136c39e27d5d2ed4da0ee5ed02bc8a9f8bf6d8" + integrity sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw== + +postcss-discard-overridden@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz#454b41f707300b98109a75005ca4ab0ff2743ac6" + integrity sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q== + +postcss-merge-longhand@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.0.2.tgz#277ada51d9a7958e8ef8cf263103c9384b322a41" + integrity sha512-BMlg9AXSI5G9TBT0Lo/H3PfUy63P84rVz3BjCFE9e9Y9RXQZD3+h3YO1kgTNsNJy7bBc1YQp8DmSnwLIW5VPcw== + dependencies: + css-color-names "^1.0.1" + postcss-value-parser "^4.1.0" + stylehacks "^5.0.1" + +postcss-merge-rules@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.2.tgz#d6e4d65018badbdb7dcc789c4f39b941305d410a" + integrity sha512-5K+Md7S3GwBewfB4rjDeol6V/RZ8S+v4B66Zk2gChRqLTCC8yjnHQ601omj9TKftS19OPGqZ/XzoqpzNQQLwbg== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + cssnano-utils "^2.0.1" + postcss-selector-parser "^6.0.5" + vendors "^1.0.3" + +postcss-minify-font-values@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz#a90cefbfdaa075bd3dbaa1b33588bb4dc268addf" + integrity sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-minify-gradients@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.2.tgz#7c175c108f06a5629925d698b3c4cf7bd3864ee5" + integrity sha512-7Do9JP+wqSD6Prittitt2zDLrfzP9pqKs2EcLX7HJYxsxCOwrrcLt4x/ctQTsiOw+/8HYotAoqNkrzItL19SdQ== + dependencies: + colord "^2.6" + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-minify-params@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.0.1.tgz#371153ba164b9d8562842fdcd929c98abd9e5b6c" + integrity sha512-4RUC4k2A/Q9mGco1Z8ODc7h+A0z7L7X2ypO1B6V8057eVK6mZ6xwz6QN64nHuHLbqbclkX1wyzRnIrdZehTEHw== + dependencies: + alphanum-sort "^1.0.2" + browserslist "^4.16.0" + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + uniqs "^2.0.0" + +postcss-minify-selectors@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz#4385c845d3979ff160291774523ffa54eafd5a54" + integrity sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og== + dependencies: + alphanum-sort "^1.0.2" + postcss-selector-parser "^6.0.5" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-normalize-charset@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz#121559d1bebc55ac8d24af37f67bd4da9efd91d0" + integrity sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg== + +postcss-normalize-display-values@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz#62650b965981a955dffee83363453db82f6ad1fd" + integrity sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-normalize-positions@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz#868f6af1795fdfa86fbbe960dceb47e5f9492fe5" + integrity sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-normalize-repeat-style@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz#cbc0de1383b57f5bb61ddd6a84653b5e8665b2b5" + integrity sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-normalize-string@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz#d9eafaa4df78c7a3b973ae346ef0e47c554985b0" + integrity sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-normalize-timing-functions@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz#8ee41103b9130429c6cbba736932b75c5e2cb08c" + integrity sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-normalize-unicode@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz#82d672d648a411814aa5bf3ae565379ccd9f5e37" + integrity sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA== + dependencies: + browserslist "^4.16.0" + postcss-value-parser "^4.1.0" + +postcss-normalize-url@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.2.tgz#ddcdfb7cede1270740cf3e4dfc6008bd96abc763" + integrity sha512-k4jLTPUxREQ5bpajFQZpx8bCF2UrlqOTzP9kEqcEnOfwsRshWs2+oAFIHfDQB8GO2PaUaSE0NlTAYtbluZTlHQ== + dependencies: + is-absolute-url "^3.0.3" + normalize-url "^6.0.1" + postcss-value-parser "^4.1.0" + +postcss-normalize-whitespace@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz#b0b40b5bcac83585ff07ead2daf2dcfbeeef8e9a" + integrity sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-ordered-values@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.2.tgz#1f351426977be00e0f765b3164ad753dac8ed044" + integrity sha512-8AFYDSOYWebJYLyJi3fyjl6CqMEG/UVworjiyK1r573I56kb3e879sCJLGvR3merj+fAdPpVplXKQZv+ey6CgQ== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-reduce-initial@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz#9d6369865b0f6f6f6b165a0ef5dc1a4856c7e946" + integrity sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw== + dependencies: + browserslist "^4.16.0" + caniuse-api "^3.0.0" + +postcss-reduce-transforms@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz#93c12f6a159474aa711d5269923e2383cedcf640" + integrity sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5: + version "6.0.6" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" + integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-svgo@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.2.tgz#bc73c4ea4c5a80fbd4b45e29042c34ceffb9257f" + integrity sha512-YzQuFLZu3U3aheizD+B1joQ94vzPfE6BNUcSYuceNxlVnKKsOtdo6hL9/zyC168Q8EwfLSgaDSalsUGa9f2C0A== + dependencies: + postcss-value-parser "^4.1.0" + svgo "^2.3.0" + +postcss-unique-selectors@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.0.1.tgz#3be5c1d7363352eff838bd62b0b07a0abad43bfc" + integrity sha512-gwi1NhHV4FMmPn+qwBNuot1sG1t2OmacLQ/AX29lzyggnjd+MnVD5uqQmpXO3J17KGL2WAxQruj1qTd3H0gG/w== + dependencies: + alphanum-sort "^1.0.2" + postcss-selector-parser "^6.0.5" + uniqs "^2.0.0" + +postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== + +postcss@^8.2.1, postcss@^8.2.15: + version "8.3.9" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.9.tgz#98754caa06c4ee9eb59cc48bd073bb6bd3437c31" + integrity sha512-f/ZFyAKh9Dnqytx5X62jgjhhzttjZS7hMsohcI7HEI5tjELX/HxCy3EFhsRxyzGvrzFF+82XPvCS8T9TFleVJw== + dependencies: + nanoid "^3.1.28" + picocolors "^0.2.1" + source-map-js "^0.6.2" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process-on-spawn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/process-on-spawn/-/process-on-spawn-1.0.0.tgz#95b05a23073d30a17acfdc92a440efd2baefdc93" + integrity sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg== + dependencies: + fromentries "^1.2.0" + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +reflect-metadata@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp-tree@^0.1.21, regexp-tree@~0.1.1: + version "0.1.24" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.24.tgz#3d6fa238450a4d66e5bc9c4c14bb720e2196829d" + integrity sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw== + +regexpp@^3.0.0, regexpp@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +release-zalgo@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" + integrity sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA= + dependencies: + es6-error "^4.0.1" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +reserved-words@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/reserved-words/-/reserved-words-0.1.2.tgz#00a0940f98cd501aeaaac316411d9adc52b31ab1" + integrity sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE= + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.10.0, resolve@^1.20.0, resolve@^1.3.2: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^2.5.4, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rxjs@^6.6.7: + version "6.6.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== + dependencies: + tslib "^1.9.0" + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +safe-regex@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-2.1.1.tgz#f7128f00d056e2fe5c11e81a1324dd974aadced2" + integrity sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A== + dependencies: + regexp-tree "~0.1.1" + +safer-buffer@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +schema-utils@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + +semver-regex@^3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.3.tgz#b2bcc6f97f63269f286994e297e229b6245d0dc3" + integrity sha512-Aqi54Mk9uYTjVexLnR67rTyBusmwd04cLkHy9hNvk3+G3nT2Oyg7E0l4XVbOaNwIvQ3hHeYxGcyEy+mKreyBFQ== + +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@7.3.5, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@^1.6.1: + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.2: + version "3.0.5" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" + integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== + +sirv@^1.0.7: + version "1.0.17" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.17.tgz#86e2c63c612da5a1dace1c16c46f524aaa26ac45" + integrity sha512-qx9go5yraB7ekT7bCMqUHJ5jEaOC/GXBxUWv+jeWnb7WzHUFdcQPGWk7YmAwFBaQBrogpuSqd/azbC2lZRqqmw== + dependencies: + "@polka/url" "^1.0.0-next.20" + mime "^2.3.1" + totalist "^1.0.0" + +size-limit@^4.5.7: + version "4.12.0" + resolved "https://registry.yarnpkg.com/size-limit/-/size-limit-4.12.0.tgz#ecc9c0448c049a40b10e76b5e1b4a20f99a54468" + integrity sha512-LwlUDPxFJbJDIJsBE5bKo8kFMuxmuewBMDjgfSoQwnO27V8DSK+j6881nsrX3GoM3bJMFIeEq56thqBEdYC8bw== + dependencies: + bytes-iec "^3.1.1" + chokidar "^3.5.1" + ci-job-number "^1.2.2" + colorette "^1.2.2" + globby "^11.0.3" + lilconfig "^2.0.3" + ora "^5.4.1" + read-pkg-up "^7.0.1" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.5.17, source-map-support@~0.5.12: + version "0.5.20" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" + integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spawn-wrap@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-2.0.0.tgz#103685b8b8f9b79771318827aa78650a610d457e" + integrity sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg== + dependencies: + foreground-child "^2.0.0" + is-windows "^1.0.2" + make-dir "^3.0.0" + rimraf "^3.0.0" + signal-exit "^3.0.2" + which "^2.0.1" + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.10" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz#0d9becccde7003d6c658d487dd48a32f0bf3014b" + integrity sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +ssri@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" + integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== + dependencies: + figgy-pudding "^3.5.1" + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +string-argv@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" + integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string.prototype.padend@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz#997a6de12c92c7cb34dc8a201a6c53d9bd88a5f1" + integrity sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +style-loader@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c" + integrity sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +stylehacks@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.0.1.tgz#323ec554198520986806388c7fdaebc38d2c06fb" + integrity sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA== + dependencies: + browserslist "^4.16.0" + postcss-selector-parser "^6.0.4" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +svgo@^2.3.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.7.0.tgz#e164cded22f4408fe4978f082be80159caea1e2d" + integrity sha512-aDLsGkre4fTDCWvolyW+fs8ZJFABpzLXbtdK1y71CKnHzAnpDxKXPj2mNKj+pyOXUCzFHzuxRJ94XOFygOWV3w== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^4.1.3" + css-tree "^1.1.3" + csso "^4.2.0" + nanocolors "^0.1.12" + stable "^0.1.8" + +table@^6.0.9: + version "6.7.2" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.2.tgz#a8d39b9f5966693ca8b0feba270a78722cbaf3b0" + integrity sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g== + dependencies: + ajv "^8.0.1" + lodash.clonedeep "^4.5.0" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +terser-webpack-plugin@^1.4.3: + version "1.4.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" + integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^4.0.0" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^4.1.2: + version "4.8.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" + integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +timers-browserify@^2.0.4: + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== + dependencies: + setimmediate "^1.0.4" + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +totalist@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" + integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== + +ts-node@^8.10.2: + version "8.10.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d" + integrity sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA== + dependencies: + arg "^4.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" + +ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== + +tsconfig-paths@^3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" + integrity sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.0" + strip-bom "^3.0.0" + +tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + +tslint@^6.1.2: + version "6.1.3" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904" + integrity sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg== + dependencies: + "@babel/code-frame" "^7.0.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^4.0.1" + glob "^7.1.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + mkdirp "^0.5.3" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.13.0" + tsutils "^2.29.0" + +tsutils@^2.29.0: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + +tsutils@^3.17.1: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + +type-fest@^0.8.0, type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +typescript@^3.9.7: + version "3.9.10" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" + integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +uuid@^3.3.3: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +v8-compile-cache@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vendors@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" + integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== + dependencies: + chokidar "^2.1.8" + +watchpack@^1.7.4: + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== + dependencies: + graceful-fs "^4.1.2" + neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.1" + watchpack-chokidar2 "^2.0.1" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + dependencies: + defaults "^1.0.3" + +webpack-bundle-analyzer@^4.4.2: + version "4.5.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz#1b0eea2947e73528754a6f9af3e91b2b6e0f79d5" + integrity sha512-GUMZlM3SKwS8Z+CKeIFx7CVoHn3dXFcUAjT/dcZQQmfSZGvitPfMob2ipjai7ovFFqPvTqkEZ/leL4O0YOdAYQ== + dependencies: + acorn "^8.0.4" + acorn-walk "^8.0.0" + chalk "^4.1.0" + commander "^7.2.0" + gzip-size "^6.0.0" + lodash "^4.17.20" + opener "^1.5.2" + sirv "^1.0.7" + ws "^7.3.1" + +webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.44.1: + version "4.46.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" + integrity sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.5.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.3" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.7.4" + webpack-sources "^1.4.1" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which-pm-runs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" + integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +ws@^7.3.1: + version "7.5.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" + integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0, yaml@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^15.0.2: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==