diff --git a/AISKU/src/ApplicationInsightsDeprecated.ts b/AISKU/src/ApplicationInsightsDeprecated.ts index 45d9a36dd..89abf077d 100644 --- a/AISKU/src/ApplicationInsightsDeprecated.ts +++ b/AISKU/src/ApplicationInsightsDeprecated.ts @@ -3,7 +3,7 @@ import { IConfig, PageViewPerformance, SeverityLevel, Util, IAutoExceptionTelemetry, IDependencyTelemetry, IExceptionTelemetry, IEventTelemetry, IEnvelope, ProcessLegacy, HttpMethod } from "@microsoft/applicationinsights-common"; import { Snippet, Initialization as ApplicationInsights } from "./Initialization"; -import { ITelemetryItem, IDiagnosticLogger, IConfiguration } from "@microsoft/applicationinsights-core-js"; +import { ITelemetryItem, IDiagnosticLogger, IConfiguration, CoreUtils, objForEachKey } from "@microsoft/applicationinsights-core-js"; // ToDo: fix properties and measurements once updates are done to common export class AppInsightsDeprecated implements IAppInsightsDeprecated { @@ -170,11 +170,11 @@ export class AppInsightsDeprecated implements IAppInsightsDeprecated { public updateSnippetDefinitions(snippet: Snippet) { // apply full appInsights to the global instance // Note: This must be called before loadAppInsights is called - for (const field in this) { - if (typeof field === 'string') { - snippet[field as string] = this[field]; + objForEachKey(this, (field, value) => { + if (CoreUtils.isString(field)) { + snippet[field as string] = value; } - } + }); } // note: these are split into methods to enable unit tests diff --git a/AISKU/src/Initialization.ts b/AISKU/src/Initialization.ts index dc6658b3f..2858199c4 100644 --- a/AISKU/src/Initialization.ts +++ b/AISKU/src/Initialization.ts @@ -3,7 +3,7 @@ import { CoreUtils, IConfiguration, AppInsightsCore, IAppInsightsCore, LoggingSeverity, _InternalMessageId, ITelemetryItem, ICustomProperties, - IChannelControls, hasWindow, hasDocument, isReactNative, doPerf, IDiagnosticLogger, INotificationManager + IChannelControls, hasWindow, hasDocument, isReactNative, doPerf, IDiagnosticLogger, INotificationManager, objForEachKey } from "@microsoft/applicationinsights-core-js"; import { ApplicationInsights } from "@microsoft/applicationinsights-analytics-js"; import { Sender } from "@microsoft/applicationinsights-channel-js"; @@ -292,13 +292,13 @@ export class Initialization implements IApplicationInsights { } // apply updated properties to the global instance (snippet) - for (const field in _self) { + objForEachKey(_self, (field, value) => { if (CoreUtils.isString(field) && - !CoreUtils.isFunction(_self[field]) && + !CoreUtils.isFunction(value) && field.substring(0, 1) !== "_") { // Don't copy "internal" values - snippet[field as string] = _self[field]; + snippet[field as string] = value; } - } + }); } } @@ -342,11 +342,11 @@ export class Initialization implements IApplicationInsights { public updateSnippetDefinitions(snippet: Snippet) { // apply full appInsights to the global instance // Note: This must be called before loadAppInsights is called - for (const field in this) { + objForEachKey(this, (field, value) => { if (CoreUtils.isString(field)) { - snippet[field as string] = this[field]; + snippet[field as string] = value; } - } + }); } /** diff --git a/channels/applicationinsights-channel-js/src/EnvelopeCreator.ts b/channels/applicationinsights-channel-js/src/EnvelopeCreator.ts index 62c33d2ec..85716c108 100644 --- a/channels/applicationinsights-channel-js/src/EnvelopeCreator.ts +++ b/channels/applicationinsights-channel-js/src/EnvelopeCreator.ts @@ -10,7 +10,7 @@ import { import { ITelemetryItem, CoreUtils, IDiagnosticLogger, LoggingSeverity, _InternalMessageId, - hasJSON, getJSON + hasJSON, getJSON, objForEachKey } from '@microsoft/applicationinsights-core-js'; // these two constants are used to filter out properties not needed when trying to extract custom properties and measurements from the incoming payload @@ -19,7 +19,6 @@ const strBaseData = 'baseData'; const strProperties = 'properties'; const strTrue = 'true'; const arrForEach = CoreUtils.arrForEach; -const objKeys = CoreUtils.objKeys; const isNullOrUndefined = CoreUtils.isNullOrUndefined; function _setValueIf(target:T, field:keyof T, value:any) { @@ -36,8 +35,7 @@ export abstract class EnvelopeCreator { protected static extractPropsAndMeasurements(data: { [key: string]: any }, properties: { [key: string]: any }, measurements: { [key: string]: any }) { if (!isNullOrUndefined(data)) { - arrForEach(objKeys(data), (key) => { - const value = data[key]; + objForEachKey(data, (key, value) => { if (CoreUtils.isNumber(value)) { measurements[key] = value; } else if (CoreUtils.isString(value)) { @@ -149,17 +147,16 @@ export abstract class EnvelopeCreator { // deals with tags.push({object}) for(let i = itmTags.length - 1; i >= 0; i--){ const tg = itmTags[i]; - // CoreUtils.objKeys returns an array of keys - arrForEach(objKeys(tg), key => { - tgs[key] = tg[key]; + objForEachKey(tg, (key, value) => { + tgs[key] = value; }); itmTags.splice(i, 1); } // deals with tags[key]=value (and handles hasOwnProperty) - arrForEach(objKeys(itmTags), (tg) => { - tgs[tg] = itmTags[tg]; + objForEachKey(itmTags, (tg, value) => { + tgs[tg] = value; }); env.tags = { ...envTags, ...tgs }; @@ -321,8 +318,8 @@ export class PageViewEnvelopeCreator extends EnvelopeCreator { // pageTags is a field that Breeze still does not recognize as part of Part B. For now, put it in Part C until it supports it as a domain property if (!isNullOrUndefined(bd[strProperties])) { const pageTags = bd[strProperties]; - arrForEach(objKeys(pageTags), (key) => { - properties[key] = pageTags[key]; + objForEachKey(pageTags, (key, value) => { + properties[key] = value; }); } diff --git a/channels/applicationinsights-channel-js/src/Sender.ts b/channels/applicationinsights-channel-js/src/Sender.ts index 1459a94c3..acf86a9ed 100644 --- a/channels/applicationinsights-channel-js/src/Sender.ts +++ b/channels/applicationinsights-channel-js/src/Sender.ts @@ -21,7 +21,7 @@ import { ITelemetryItem, IProcessTelemetryContext, IConfiguration, CoreUtils, _InternalMessageId, LoggingSeverity, IDiagnosticLogger, IAppInsightsCore, IPlugin, getWindow, getNavigator, getJSON, BaseTelemetryPlugin, ITelemetryPluginChain, INotificationManager, - SendRequestReason, getGlobalInst + SendRequestReason, getGlobalInst, objForEachKey } from '@microsoft/applicationinsights-core-js'; import { Offline } from './Offline'; import { Sample } from './TelemetryProcessors/Sample' @@ -216,9 +216,9 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControlsAI { _self._sender = null; const defaultConfig = Sender._getDefaultAppInsightsChannelConfig(); _self._senderConfig = Sender._getEmptyAppInsightsChannelConfig(); - for (const field in defaultConfig) { - _self._senderConfig[field] = () => ctx.getConfig(identifier, field, defaultConfig[field]()); - } + objForEachKey(defaultConfig, (field, value) => { + _self._senderConfig[field] = () => ctx.getConfig(identifier, field, value()); + }); _self._buffer = (_self._senderConfig.enableSessionStorageBuffer() && Util.canUseSessionStorage()) ? new SessionStorageSendBuffer(_self.diagLog(), _self._senderConfig) : new ArraySendBuffer(_self._senderConfig); diff --git a/channels/applicationinsights-channel-js/src/Serializer.ts b/channels/applicationinsights-channel-js/src/Serializer.ts index dfde58fb5..4e084fdfc 100644 --- a/channels/applicationinsights-channel-js/src/Serializer.ts +++ b/channels/applicationinsights-channel-js/src/Serializer.ts @@ -1,5 +1,5 @@ import { Util, ISerializable, FieldType } from '@microsoft/applicationinsights-common'; -import { IDiagnosticLogger, LoggingSeverity, _InternalMessageId, CoreUtils, getJSON } from '@microsoft/applicationinsights-core-js'; +import { IDiagnosticLogger, LoggingSeverity, _InternalMessageId, CoreUtils, getJSON, objForEachKey } from '@microsoft/applicationinsights-core-js'; import dynamicProto from '@microsoft/dynamicproto-js' export class Serializer { @@ -60,9 +60,7 @@ export class Serializer { } source[circularReferenceCheck] = true; - for (const field in source.aiDataContract) { - - const contract = source.aiDataContract[field]; + objForEachKey(source.aiDataContract, (field, contract) => { const isRequired = (CoreUtils.isFunction(contract)) ? (contract() & FieldType.Required) : (contract & FieldType.Required); const isHidden = (CoreUtils.isFunction(contract)) ? (contract() & FieldType.Hidden) : (contract & FieldType.Hidden); const isArray = contract & FieldType.Array; @@ -78,33 +76,27 @@ export class Serializer { { field, name }); // If not in debug mode, continue and hope the error is permissible - continue; - } - - if (isHidden) { - // Don't serialize hidden fields - continue; - } - - let value; - if (isObject) { - if (isArray) { - // special case; recurse on each object in the source array - value = _serializeArray(source[field], field); + } else if (!isHidden) { // Don't serialize hidden fields + let value; + if (isObject) { + if (isArray) { + // special case; recurse on each object in the source array + value = _serializeArray(source[field], field); + } else { + // recurse on the source object in this field + value = _serializeObject(source[field], field); + } } else { - // recurse on the source object in this field - value = _serializeObject(source[field], field); + // assign the source field to the output even if undefined or required + value = source[field]; } - } else { - // assign the source field to the output even if undefined or required - value = source[field]; - } - // only emit this field if the value is defined - if (value !== undefined) { - output[field] = value; + // only emit this field if the value is defined + if (value !== undefined) { + output[field] = value; + } } - } + }); delete source[circularReferenceCheck]; return output; @@ -134,11 +126,10 @@ export class Serializer { } function _serializeStringMap(map: any, expectedType: string, name: string) { - let output; + let output: any; if (map) { output = {}; - for (const field in map) { - const value = map[field]; + objForEachKey(map, (field, value) => { if (expectedType === "string") { if (value === undefined) { output[field] = "undefined"; @@ -170,7 +161,7 @@ export class Serializer { output[field] = "invalid field: " + name + " is of unknown type."; logger.throwInternal(LoggingSeverity.CRITICAL, output[field], null, true); } - } + }); } return output; diff --git a/common/config/rush/npm-shrinkwrap.json b/common/config/rush/npm-shrinkwrap.json index a060dc4aa..89c60cb7d 100644 --- a/common/config/rush/npm-shrinkwrap.json +++ b/common/config/rush/npm-shrinkwrap.json @@ -150,14 +150,14 @@ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz" }, "@types/node": { - "version": "14.11.10", + "version": "14.14.6", "from": "@types/node@*", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.10.tgz" + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz" }, "@types/qunit": { - "version": "2.9.5", + "version": "2.9.6", "from": "@types/qunit@^2.5.3", - "resolved": "https://registry.npmjs.org/@types/qunit/-/qunit-2.9.5.tgz" + "resolved": "https://registry.npmjs.org/@types/qunit/-/qunit-2.9.6.tgz" }, "@types/sinon": { "version": "4.3.3", @@ -338,9 +338,9 @@ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" }, "aws4": { - "version": "1.10.1", + "version": "1.11.0", "from": "aws4@^1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz" + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz" }, "balanced-match": { "version": "1.0.0", @@ -885,9 +885,9 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" }, "fastq": { - "version": "1.8.0", + "version": "1.9.0", "from": "fastq@^1.6.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz" + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz" }, "fd-slicer": { "version": "1.1.0", @@ -973,6 +973,11 @@ "from": "fs.realpath@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" }, + "function-bind": { + "version": "1.1.1", + "from": "function-bind@>=1.1.1 <2.0.0", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + }, "get-stdin": { "version": "4.0.1", "from": "get-stdin@>=4.0.1 <5.0.0", @@ -1145,6 +1150,11 @@ "from": "har-validator@~5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz" }, + "has": { + "version": "1.0.3", + "from": "has@>=1.0.3 <2.0.0", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + }, "has-ansi": { "version": "2.0.0", "from": "has-ansi@>=2.0.0 <3.0.0", @@ -1273,6 +1283,11 @@ "from": "is-buffer@>=1.1.5 <2.0.0", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" }, + "is-core-module": { + "version": "2.0.0", + "from": "is-core-module@^2.0.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.0.0.tgz" + }, "is-data-descriptor": { "version": "0.1.4", "from": "is-data-descriptor@>=0.1.4 <0.2.0", @@ -1967,9 +1982,9 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz" }, "resolve": { - "version": "1.17.0", + "version": "1.18.1", "from": "resolve@^1.10.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz" + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz" }, "resolve-url": { "version": "0.2.1", @@ -2056,9 +2071,9 @@ "resolved": "https://registry.npmjs.org/rollup-plugin-uglify/-/rollup-plugin-uglify-6.0.4.tgz", "dependencies": { "uglify-js": { - "version": "3.11.2", + "version": "3.11.5", "from": "uglify-js@^3.4.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.2.tgz" + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.5.tgz" } } }, @@ -2068,9 +2083,9 @@ "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz" }, "run-parallel": { - "version": "1.1.9", - "from": "run-parallel@>=1.1.9 <2.0.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz" + "version": "1.1.10", + "from": "run-parallel@^1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz" }, "safe-buffer": { "version": "5.1.2", diff --git a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/ApplicationInsights.ts b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/ApplicationInsights.ts index b84c18b34..24af53f9f 100644 --- a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/ApplicationInsights.ts +++ b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/ApplicationInsights.ts @@ -15,7 +15,7 @@ import { IPlugin, IConfiguration, IAppInsightsCore, BaseTelemetryPlugin, CoreUtils, ITelemetryItem, IProcessTelemetryContext, ITelemetryPluginChain, IDiagnosticLogger, LoggingSeverity, _InternalMessageId, ICustomProperties, - getWindow, getDocument, getHistory, getLocation, doPerf + getWindow, getDocument, getHistory, getLocation, doPerf, objForEachKey } from "@microsoft/applicationinsights-core-js"; import { PageViewManager, IAppInsightsInternal } from "./Telemetry/PageViewManager"; import { PageVisitTimeManager } from "./Telemetry/PageVisitTimeManager"; @@ -487,17 +487,17 @@ export class ApplicationInsights extends BaseTelemetryPlugin implements IAppInsi // load default values if specified const defaults: IConfig = ApplicationInsights.getDefaultConfig(); if (defaults !== undefined) { - for (const field in defaults) { + objForEachKey(defaults, (field, value) => { // for each unspecified field, set the default value - this.config[field] = ctx.getConfig(identifier, field, defaults[field]); - } + this.config[field] = ctx.getConfig(identifier, field, value); + }); if (this._globalconfig) { - for (const field in defaults) { + objForEachKey(defaults, (field, value) => { if (this._globalconfig[field] === undefined) { - this._globalconfig[field] = defaults[field]; + this._globalconfig[field] = value; } - } + }); } } diff --git a/extensions/applicationinsights-debugplugin-js/src/DebugPlugin.ts b/extensions/applicationinsights-debugplugin-js/src/DebugPlugin.ts index c28c0e08d..51b43d275 100644 --- a/extensions/applicationinsights-debugplugin-js/src/DebugPlugin.ts +++ b/extensions/applicationinsights-debugplugin-js/src/DebugPlugin.ts @@ -4,7 +4,7 @@ import { BaseTelemetryPlugin, IConfiguration, CoreUtils, IAppInsightsCore, IPlugin, ITelemetryItem, IProcessTelemetryContext, _InternalLogMessage, _InternalMessageId, - ITelemetryPluginChain, InstrumentFunc, IInstrumentCallDetails, InstrumentorHooksCallback, IPerfEvent, IChannelControls + ITelemetryPluginChain, InstrumentFunc, IInstrumentCallDetails, InstrumentorHooksCallback, IPerfEvent, IChannelControls, objForEachKey } from '@microsoft/applicationinsights-core-js'; import { Dashboard } from './components/Dashboard'; import { getTargetName } from './components/helpers'; @@ -123,8 +123,8 @@ export default class DebugPlugin extends BaseTelemetryPlugin { const defaultConfig = getDefaultConfig(); const ctx = _self._getTelCtx(); const identifier = _self.identifier; - _arrForEach(CoreUtils.objKeys(defaultConfig), (field) => { - _theConfig[field] = () => ctx.getConfig(identifier, field, defaultConfig[field]()); + objForEachKey(defaultConfig, (field, value) => { + _theConfig[field] = () => ctx.getConfig(identifier, field, value()); }); let foundTrackers: string[] = []; @@ -177,7 +177,7 @@ export default class DebugPlugin extends BaseTelemetryPlugin { // 2. Get all of the extensions and channels debugBins = {}; - let targetObjects: any = [core, _self.diagLog()]; + let targetObjects: any[] = [core, _self.diagLog()]; // Get all of the config extensions if (config.extensions) { diff --git a/extensions/applicationinsights-dependencies-js/src/ajax.ts b/extensions/applicationinsights-dependencies-js/src/ajax.ts index 3e749f852..f7db5d72e 100644 --- a/extensions/applicationinsights-dependencies-js/src/ajax.ts +++ b/extensions/applicationinsights-dependencies-js/src/ajax.ts @@ -10,7 +10,7 @@ import { CoreUtils, LoggingSeverity, _InternalMessageId, IAppInsightsCore, BaseTelemetryPlugin, ITelemetryPluginChain, IConfiguration, IPlugin, ITelemetryItem, IProcessTelemetryContext, getLocation, getGlobal, strUndefined, strPrototype, IInstrumentCallDetails, InstrumentFunc, InstrumentProto, getPerformance, - IInstrumentHooksCallbacks, IInstrumentHook + IInstrumentHooksCallbacks, IInstrumentHook, objForEachKey } from '@microsoft/applicationinsights-core-js'; import { ajaxRecord, IAjaxRecordResponse } from './ajaxRecord'; import { EventHelper } from './ajaxUtils'; @@ -25,7 +25,6 @@ const strFetch = "fetch"; let _isNullOrUndefined = CoreUtils.isNullOrUndefined; let _arrForEach = CoreUtils.arrForEach; -let _objKeys = CoreUtils.objKeys; // Using a global value so that to handle same iKey with multiple app insights instances (mostly for testing) let _markCount: number = 0; @@ -181,7 +180,7 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu public static getEmptyConfig(): ICorrelationConfig { let emptyConfig = this.getDefaultConfig(); - _arrForEach(_objKeys(emptyConfig), (value) => { + objForEachKey(emptyConfig, (value) => { emptyConfig[value] = undefined; }); @@ -218,8 +217,8 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu base.initialize(config, core, extensions, pluginChain); let ctx = _self._getTelCtx(); const defaultConfig = AjaxMonitor.getDefaultConfig(); - _arrForEach(_objKeys(defaultConfig), (field) => { - _config[field] = ctx.getConfig(AjaxMonitor.identifier, field, defaultConfig[field]); + objForEachKey(defaultConfig, (field, value) => { + _config[field] = ctx.getConfig(AjaxMonitor.identifier, field, value); }); let distributedTracingMode = _config.distributedTracingMode; diff --git a/extensions/applicationinsights-dependencies-js/src/ajaxRecord.ts b/extensions/applicationinsights-dependencies-js/src/ajaxRecord.ts index 389cfe23f..139282e3c 100644 --- a/extensions/applicationinsights-dependencies-js/src/ajaxRecord.ts +++ b/extensions/applicationinsights-dependencies-js/src/ajaxRecord.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. import { DataSanitizer, UrlHelper, DateTimeUtils, IDependencyTelemetry, Util } from '@microsoft/applicationinsights-common'; -import { IDiagnosticLogger, CoreUtils, normalizeJsName } from '@microsoft/applicationinsights-core-js'; +import { IDiagnosticLogger, CoreUtils, normalizeJsName, objForEachKey } from '@microsoft/applicationinsights-core-js'; import dynamicProto from "@microsoft/dynamicproto-js"; export interface IAjaxRecordResponse { @@ -144,8 +144,7 @@ function _populatePerfData(ajaxData:ajaxRecord, dependency:IDependencyTelemetry) _arrForEach(serverTiming, (value, idx) => { let name = normalizeJsName(value[strName] || "" + idx); let newValue = server[name] || {}; - _arrForEach(_objKeys(value), (key) => { - let val = value[key]; + objForEachKey(value, (key, val) => { if (key !== strName && _isString(val) || CoreUtils.isNumber(val)) { if (newValue[key]) { val = newValue[key] + ";" + val; diff --git a/extensions/applicationinsights-properties-js/src/PropertiesPlugin.ts b/extensions/applicationinsights-properties-js/src/PropertiesPlugin.ts index 561f36cd8..7ddca8b26 100644 --- a/extensions/applicationinsights-properties-js/src/PropertiesPlugin.ts +++ b/extensions/applicationinsights-properties-js/src/PropertiesPlugin.ts @@ -6,7 +6,7 @@ import { BaseTelemetryPlugin, IConfiguration, CoreUtils, IAppInsightsCore, IPlugin, ITelemetryItem, IProcessTelemetryContext, _InternalLogMessage, LoggingSeverity, _InternalMessageId, getNavigator, - ITelemetryPluginChain + ITelemetryPluginChain, objForEachKey } from '@microsoft/applicationinsights-core-js'; import { TelemetryContext } from './TelemetryContext'; import { PageView, ConfigurationManager, @@ -45,9 +45,9 @@ export default class PropertiesPlugin extends BaseTelemetryPlugin implements IPr let identifier = this.identifier; const defaultConfig: ITelemetryConfig = PropertiesPlugin.getDefaultConfig(); this._extensionConfig = this._extensionConfig || PropertiesPlugin.getDefaultConfig(); - for (const field in defaultConfig) { - this._extensionConfig[field] = () => ctx.getConfig(identifier, field, defaultConfig[field]()); - } + objForEachKey(defaultConfig, (field, value) => { + this._extensionConfig[field] = () => ctx.getConfig(identifier, field, value()); + }); this.context = new TelemetryContext(core.logger, this._extensionConfig); this._breezeChannel = Util.getExtension(extensions, BreezeChannelIdentifier); diff --git a/extensions/applicationinsights-react-native/src/ReactNativePlugin.ts b/extensions/applicationinsights-react-native/src/ReactNativePlugin.ts index 610179277..f51ca6136 100644 --- a/extensions/applicationinsights-react-native/src/ReactNativePlugin.ts +++ b/extensions/applicationinsights-react-native/src/ReactNativePlugin.ts @@ -12,7 +12,8 @@ import { LoggingSeverity, _InternalMessageId, BaseTelemetryPlugin, - IProcessTelemetryContext + IProcessTelemetryContext, + objForEachKey } from '@microsoft/applicationinsights-core-js'; import { ConfigurationManager, IDevice, IExceptionTelemetry, IAppInsights, SeverityLevel, AnalyticsPluginIdentifier } from '@microsoft/applicationinsights-common'; import DeviceInfo from 'react-native-device-info'; @@ -45,14 +46,14 @@ export class ReactNativePlugin extends BaseTelemetryPlugin { const inConfig = config || {}; const defaultConfig = _getDefaultConfig(); - for (const option in defaultConfig) { + objForEachKey(defaultConfig, (option, value) => { _config[option] = ConfigurationManager.getConfig( inConfig as any, option, _self.identifier, - _config[option] + value ); - } + }); if (!_config.disableDeviceCollection) { _collectDeviceInfo(); diff --git a/shared/AppInsightsCommon/src/Telemetry/Common/DataSanitizer.ts b/shared/AppInsightsCommon/src/Telemetry/Common/DataSanitizer.ts index 410d874bc..bd800b078 100644 --- a/shared/AppInsightsCommon/src/Telemetry/Common/DataSanitizer.ts +++ b/shared/AppInsightsCommon/src/Telemetry/Common/DataSanitizer.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { IDiagnosticLogger, LoggingSeverity, _InternalMessageId, CoreUtils, hasJSON, getJSON } from '@microsoft/applicationinsights-core-js'; +import { IDiagnosticLogger, LoggingSeverity, _InternalMessageId, CoreUtils, hasJSON, getJSON, objForEachKey } from '@microsoft/applicationinsights-core-js'; export class DataSanitizer { @@ -132,8 +132,7 @@ export class DataSanitizer { public static sanitizeProperties(logger: IDiagnosticLogger, properties: any) { if (properties) { const tempProps = {}; - for (let prop in properties) { - let value = properties[prop]; + objForEachKey(properties, (prop, value) => { if (CoreUtils.isObject(value) && hasJSON()) { // Stringify any part C properties try { @@ -145,7 +144,7 @@ export class DataSanitizer { value = DataSanitizer.sanitizeString(logger, value, DataSanitizer.MAX_PROPERTY_LENGTH); prop = DataSanitizer.sanitizeKeyAndAddUniqueness(logger, prop, tempProps); tempProps[prop] = value; - } + }); properties = tempProps; } @@ -155,11 +154,11 @@ export class DataSanitizer { public static sanitizeMeasurements(logger: IDiagnosticLogger, measurements: any) { if (measurements) { const tempMeasurements = {}; - for (let measure in measurements) { - const value = measurements[measure]; + objForEachKey(measurements, (measure, value) => { measure = DataSanitizer.sanitizeKeyAndAddUniqueness(logger, measure, tempMeasurements); tempMeasurements[measure] = value; - } + }); + measurements = tempMeasurements; } diff --git a/shared/AppInsightsCommon/src/TelemetryItemCreator.ts b/shared/AppInsightsCommon/src/TelemetryItemCreator.ts index 41f8f31af..305f7cba3 100644 --- a/shared/AppInsightsCommon/src/TelemetryItemCreator.ts +++ b/shared/AppInsightsCommon/src/TelemetryItemCreator.ts @@ -3,7 +3,7 @@ import { Util } from "./Util"; import { DataSanitizer } from "./Telemetry/Common/DataSanitizer"; -import { ITelemetryItem, CoreUtils, IDiagnosticLogger } from "@microsoft/applicationinsights-core-js"; +import { ITelemetryItem, CoreUtils, IDiagnosticLogger, objForEachKey } from "@microsoft/applicationinsights-core-js"; export class TelemetryItemCreator { @@ -46,11 +46,9 @@ export class TelemetryItemCreator { // Part C if (!CoreUtils.isNullOrUndefined(customProperties)) { - for (const prop in customProperties) { - if (customProperties.hasOwnProperty(prop)) { - telemetryItem.data[prop] = customProperties[prop]; - } - } + objForEachKey(customProperties, (prop, value) => { + telemetryItem.data[prop] = value; + }); } return telemetryItem; diff --git a/shared/AppInsightsCommon/src/Util.ts b/shared/AppInsightsCommon/src/Util.ts index 483859be3..b3adb6555 100644 --- a/shared/AppInsightsCommon/src/Util.ts +++ b/shared/AppInsightsCommon/src/Util.ts @@ -5,7 +5,8 @@ import { StorageType } from "./Enums"; import { CoreUtils, EventHelper, _InternalMessageId, LoggingSeverity, IDiagnosticLogger, IPlugin, getCrypto, getMsCrypto, getGlobal, getGlobalInst, getWindow, getDocument, getNavigator, getPerformance, getLocation, hasJSON, getJSON, - strPrototype + strPrototype, + objForEachKey } from "@microsoft/applicationinsights-core-js"; import { RequestHeaders } from "./RequestResponseHeaders"; import { DataSanitizer } from "./Telemetry/Common/DataSanitizer"; @@ -227,13 +228,14 @@ export class Util { * @returns {string[]} List of session storage keys */ public static getSessionStorageKeys(): string[] { - const keys = []; + const keys: string[] = []; if (Util.canUseSessionStorage()) { - for (const key in getGlobalInst("sessionStorage")) { + objForEachKey(getGlobalInst("sessionStorage"), (key) => { keys.push(key); - } + }); } + return keys; } diff --git a/shared/AppInsightsCore/src/JavaScriptSDK/CoreUtils.ts b/shared/AppInsightsCore/src/JavaScriptSDK/CoreUtils.ts index becd25480..cd502f307 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK/CoreUtils.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK/CoreUtils.ts @@ -23,6 +23,11 @@ var _mwcZ = 987654321; // Takes any integer function _mwcSeed(seedValue: number) { + if (seedValue < 0) { + // Make sure we end up with a positive number and not -ve one. + seedValue >>>= 0; + } + _mwcW = (123456789 + seedValue) & MaxUInt32; _mwcZ = (987654321 - seedValue) & MaxUInt32; _mwcSeeded = true; @@ -125,6 +130,22 @@ export function normalizeJsName(name: string): string { return value; } +/** + * This is a helper function for the equivalent of arForEach(objKeys(target), callbackFn), this is a + * performance optimization to avoid the creation of a new array for large objects + * @param target The target object to find and process the keys + * @param callbackfn The function to call with the details + */ +export function objForEachKey(target: any, callbackfn: (name: string, value: any) => void) { + if (target && _isObject(target)) { + for (let prop in target) { + if (_hasOwnProperty(target, prop)) { + callbackfn.call(target, prop, target[prop]); + } + } + } +} + export class CoreUtils { public static _canUseCookies: boolean; @@ -668,4 +689,4 @@ export class EventHelper { * @return {boolean} - true if the handler was successfully added */ public static DetachEvent: (obj: any, eventNameWithoutOn: string, handlerRef: any) => void = _detachEvent; -} \ No newline at end of file +} diff --git a/shared/AppInsightsCore/src/applicationinsights-core-js.ts b/shared/AppInsightsCore/src/applicationinsights-core-js.ts index f6b5d0d96..4286e5efd 100644 --- a/shared/AppInsightsCore/src/applicationinsights-core-js.ts +++ b/shared/AppInsightsCore/src/applicationinsights-core-js.ts @@ -16,7 +16,7 @@ export { SendRequestReason } from "./JavaScriptSDK.Enums/SendRequestReason"; export { AppInsightsCore } from "./JavaScriptSDK/AppInsightsCore"; export { BaseCore } from './JavaScriptSDK/BaseCore'; export { BaseTelemetryPlugin } from './JavaScriptSDK/BaseTelemetryPlugin'; -export { CoreUtils, EventHelper, Undefined, normalizeJsName } from "./JavaScriptSDK/CoreUtils"; +export { CoreUtils, EventHelper, Undefined, normalizeJsName, objForEachKey } from "./JavaScriptSDK/CoreUtils"; export { getGlobal, getGlobalInst, hasWindow, getWindow, hasDocument, getDocument, getCrypto, getMsCrypto, hasNavigator, getNavigator, hasHistory, getHistory, getLocation, getPerformance, hasJSON, getJSON, diff --git a/tslint-base.json b/tslint-base.json index fce7284ce..c996ed178 100644 --- a/tslint-base.json +++ b/tslint-base.json @@ -21,7 +21,7 @@ "no-string-literal": false, "no-reference": false, "no-empty": false, - "forin": false, + "forin": true, "ban-types": false, "no-shadowed-variable": false, "no-implicit-dependencies": false,