UNPKG

@microsoft/applicationinsights-core-js

Version:

Microsoft Application Insights Core Javascript SDK

168 lines (166 loc) 6.47 kB
/* * Application Insights JavaScript SDK - Core, 3.3.6 * Copyright (c) Microsoft and contributors. All rights reserved. */ import { isArray, isPlainObject, objForEachKey, symbolFor, throwTypeError } from "@nevware21/ts-utils"; import { _DYN_LENGTH } from "../__DynamicConstants"; // Using Symbol.for so that if the same symbol was already created it would be returned // To handle multiple instances using potentially different versions we are not using // createUniqueNamespace() export var CFG_HANDLER_LINK = symbolFor("[[ai_dynCfg_1]]"); /** * @internal * @ignore * The symbol to tag objects / arrays with if they should not be converted */ var BLOCK_DYNAMIC = symbolFor("[[ai_blkDynCfg_1]]"); /** * @internal * @ignore * The symbol to tag objects to indicate that when included into the configuration that * they should be converted into a trackable dynamic object. */ var FORCE_DYNAMIC = symbolFor("[[ai_frcDynCfg_1]]"); export function _cfgDeepCopy(source) { if (source) { var target_1; if (isArray(source)) { target_1 = []; target_1[_DYN_LENGTH /* @min:%2elength */] = source[_DYN_LENGTH /* @min:%2elength */]; } else if (isPlainObject(source)) { target_1 = {}; } if (target_1) { // Copying index values by property name as the extensionConfig can be an array or object objForEachKey(source, function (key, value) { // Perform a deep copy of the object target_1[key] = _cfgDeepCopy(value); }); return target_1; } } return source; } /** * @internal * Get the dynamic config handler if the value is already dynamic * @returns */ export function getDynamicConfigHandler(value) { if (value) { var handler = value[CFG_HANDLER_LINK] || value; if (handler.cfg && (handler.cfg === value || handler.cfg[CFG_HANDLER_LINK] === handler)) { return handler; } } return null; } /** * Mark the provided value so that if it's included into the configuration it will NOT have * its properties converted into a dynamic (reactive) object. If the object is not a plain object * or an array (ie. a class) this function has not affect as only Objects and Arrays are converted * into dynamic objects in the dynamic configuration. * * When you have tagged a value as both {@link forceDynamicConversion} and blocked force will take precedence. * * You should only need to use this function, if you are creating dynamic "classes" from objects * which confirm to the require interface. A common case for this is during unit testing where it's * easier to create mock extensions. * * If `value` is falsy (null / undefined / 0 / empty string etc) it will not be tagged and * if there is an exception adding the property to the value (because its frozen etc) the * exception will be swallowed * * @example * ```ts * // This is a valid "extension", but it is technically an object * // So when included in the config.extensions it WILL be cloned and then * // converted into a dynamic object, where all of its properties will become * // get/set object properties and will be tracked. While this WILL still * // function, when attempt to use a mocking framework on top of this the * // functions are now technically get accessors which return a function * // and this can cause some mocking frameworks to fail. * let mockChannel = { * pause: () => { }, * resume: () => { }, * teardown: () => { }, * flush: (async: any, callBack: any) => { }, * processTelemetry: (env: any) => { }, * setNextPlugin: (next: any) => { }, * initialize: (config: any, core: any, extensions: any) => { }, * identifier: "testChannel", * priority: 1003 * }; * ``` * @param value - The object that you want to block from being converted into a * trackable dynamic object * @returns The original value */ export function blockDynamicConversion(value) { if (value && (isPlainObject(value) || isArray(value))) { try { value[BLOCK_DYNAMIC] = true; } catch (e) { // Don't throw for this case as it's an ask only } } return value; } /** * This is the reverse case of {@link blockDynamicConversion} in that this will tag an * object to indicate that it should always be converted into a dynamic trackable object * even when not an object or array. So all properties of this object will become * get / set accessor functions. * * When you have tagged a value as both {@link forceDynamicConversion} and blocked force will take precedence. * * If `value` is falsy (null / undefined / 0 / empty string etc) it will not be tagged and * if there is an exception adding the property to the value (because its frozen etc) the * exception will be swallowed. * @param value - The object that should be tagged and converted if included into a dynamic * configuration. * @returns The original value */ export function forceDynamicConversion(value) { if (value) { try { value[FORCE_DYNAMIC] = true; } catch (e) { // Don't throw for this case as it's an ask only } } return value; } /** * @internal * @ignore * Helper function to check whether an object can or should be converted into a dynamic * object. * @param value - The object to check whether it should be converted * @returns `true` if the value should be converted otherwise `false`. */ export function _canMakeDynamic(getFunc, state, value) { var result = false; // Object must exist and be truthy if (value && !getFunc[state.blkVal]) { // Tagged as always convert result = value[FORCE_DYNAMIC]; // Check that it's not explicitly tagged as blocked if (!result && !value[BLOCK_DYNAMIC]) { // Only convert plain objects or arrays by default result = isPlainObject(value) || isArray(value); } } return result; } /** * Throws an invalid access exception * @param message - The message to include in the exception */ export function throwInvalidAccess(message) { throwTypeError("InvalidAccess:" + message); } //# sourceMappingURL=DynamicSupport.js.map