Skip to content

Commit

Permalink
Fix issues with for..in usage with prototype extension libraries like…
Browse files Browse the repository at this point in the history
… ember.js and prototype.js (#1420)
  • Loading branch information
MSNev committed Nov 9, 2020
1 parent d6a1f68 commit 05a1f41
Show file tree
Hide file tree
Showing 18 changed files with 143 additions and 121 deletions.
10 changes: 5 additions & 5 deletions AISKU/src/ApplicationInsightsDeprecated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
16 changes: 8 additions & 8 deletions AISKU/src/Initialization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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;
}
}
});
}
}

Expand Down Expand Up @@ -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;
}
}
});
}

/**
Expand Down
19 changes: 8 additions & 11 deletions channels/applicationinsights-channel-js/src/EnvelopeCreator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<T>(target:T, field:keyof T, value:any) {
Expand All @@ -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)) {
Expand Down Expand Up @@ -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 };
Expand Down Expand Up @@ -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;
});
}

Expand Down
8 changes: 4 additions & 4 deletions channels/applicationinsights-channel-js/src/Sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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);
Expand Down
53 changes: 22 additions & 31 deletions channels/applicationinsights-channel-js/src/Serializer.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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;
Expand Down
45 changes: 30 additions & 15 deletions common/config/rush/npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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;
}
}
});
}
}

Expand Down
Loading

0 comments on commit 05a1f41

Please sign in to comment.