@microsoft/applicationinsights-core-js
Version:
Microsoft Application Insights Core Javascript SDK
168 lines (166 loc) • 6.47 kB
JavaScript
/*
* 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