diff --git a/.aiAutoMinify.json b/.aiAutoMinify.json index 2f6f51d47..0f16e527b 100644 --- a/.aiAutoMinify.json +++ b/.aiAutoMinify.json @@ -10,6 +10,7 @@ "eLoggingSeverity", "_eInternalMessageId", "SendRequestReason", + "TransportType", "TelemetryUnloadReason", "TelemetryUpdateReason" ] diff --git a/AISKU/Tests/Unit/src/AISKUSize.Tests.ts b/AISKU/Tests/Unit/src/AISKUSize.Tests.ts index 6e91b33be..971086141 100644 --- a/AISKU/Tests/Unit/src/AISKUSize.Tests.ts +++ b/AISKU/Tests/Unit/src/AISKUSize.Tests.ts @@ -5,10 +5,10 @@ import { Snippet } from "../../../src/Snippet"; import { utlRemoveSessionStorage } from "@microsoft/applicationinsights-common"; export class AISKUSizeCheck extends AITestClass { - private readonly MAX_RAW_SIZE = 133; - private readonly MAX_BUNDLE_SIZE = 133; - private readonly MAX_RAW_DEFLATE_SIZE = 53; - private readonly MAX_BUNDLE_DEFLATE_SIZE = 53; + private readonly MAX_RAW_SIZE = 134; + private readonly MAX_BUNDLE_SIZE = 134; + private readonly MAX_RAW_DEFLATE_SIZE = 54; + private readonly MAX_BUNDLE_DEFLATE_SIZE = 54; private readonly rawFilePath = "../dist/es5/applicationinsights-web.min.js"; // Automatically updated by version scripts private readonly currentVer = "3.0.3"; diff --git a/AISKULight/Tests/Unit/src/AISKULightSize.Tests.ts b/AISKULight/Tests/Unit/src/AISKULightSize.Tests.ts index 12cd9c18c..ff8b5a0ad 100644 --- a/AISKULight/Tests/Unit/src/AISKULightSize.Tests.ts +++ b/AISKULight/Tests/Unit/src/AISKULightSize.Tests.ts @@ -2,8 +2,8 @@ import { AITestClass, Assert } from "@microsoft/ai-test-framework"; import * as pako from "pako"; export class AISKULightSizeCheck extends AITestClass { - private readonly MAX_RAW_SIZE = 80; - private readonly MAX_BUNDLE_SIZE = 80; + private readonly MAX_RAW_SIZE = 81; + private readonly MAX_BUNDLE_SIZE = 81; private readonly MAX_RAW_DEFLATE_SIZE = 33; private readonly MAX_BUNDLE_DEFLATE_SIZE = 33; private readonly rawFilePath = "../dist/es5/applicationinsights-web-basic.min.js"; diff --git a/channels/1ds-post-js/src/DataModels.ts b/channels/1ds-post-js/src/DataModels.ts index 78d579ca5..2040f1f64 100644 --- a/channels/1ds-post-js/src/DataModels.ts +++ b/channels/1ds-post-js/src/DataModels.ts @@ -5,19 +5,10 @@ * File containing the interfaces for Post channel module. */ import { - IDiagnosticLogger, IExtendedTelemetryItem, IProcessTelemetryContext, ITelemetryPlugin, IUnloadHook, IValueSanitizer + IDiagnosticLogger, IExtendedTelemetryItem, IPayloadData, IProcessTelemetryContext, ITelemetryPlugin, IUnloadHook, IValueSanitizer, + IXHROverride } from "@microsoft/1ds-core-js"; -/** IPayloadData describes interface of payload sent via POST channel */ -export interface IPayloadData { - urlString: string; - data: Uint8Array | string; - headers?: { [name: string]: string }; - timeout?: number; - disableXhrSync?: boolean; - disableFetchKeepAlive?: boolean; -} - /** * Defines the function signature for the Payload Preprocessor. * @param payload - The Initial constructed payload that if not modified should be passed onto the callback function. @@ -245,26 +236,6 @@ export interface IChannelConfiguration { addNoResponse?: boolean; } -/** - * SendPOSTFunction type defines how an HTTP POST request is sent to an ingestion server - * @param payload - The payload object that should be sent, contains the url, bytes/string and headers for the request - * @param oncomplete - The function to call once the request has completed whether a success, failure or timeout - * @param sync - A boolean flag indicating whether the request should be sent as a synchronous request. - */ -export type SendPOSTFunction = (payload: IPayloadData, oncomplete: (status: number, headers: { [headerName: string]: string; }, response?: string) => void, sync?: boolean) => void; - -/** - * The IXHROverride interface overrides the way HTTP requests are sent. - */ -export interface IXHROverride { - /** - * This method sends data to the specified URI using a POST request. If sync is true, - * then the request is sent synchronously. The oncomplete function should always be called after the request is - * completed (either successfully or timed out or failed due to errors). - */ - sendPOST: SendPOSTFunction; -} - /** * An interface which extends the telemetry event to track send attempts. */ diff --git a/channels/1ds-post-js/src/HttpManager.ts b/channels/1ds-post-js/src/HttpManager.ts index b4dcbc9aa..e8a112482 100644 --- a/channels/1ds-post-js/src/HttpManager.ts +++ b/channels/1ds-post-js/src/HttpManager.ts @@ -5,18 +5,19 @@ */ import dynamicProto from "@microsoft/dynamicproto-js"; import { - EventSendType, FullVersionString, IAppInsightsCore, ICookieMgr, IDiagnosticLogger, IExtendedConfiguration, IPerfEvent, IUnloadHook, - SendRequestReason, TransportType, _eExtendedInternalMessageId, _eInternalMessageId, _throwInternal, _warnToConsole, arrForEach, dateNow, - doPerf, dumpObj, eLoggingSeverity, extend, getLocation, getNavigator, getTime, hasOwnProperty, isArray, isBeaconsSupported, - isFetchSupported, isNullOrUndefined, isNumber, isReactNative, isString, isUndefined, isValueAssigned, isXhrSupported, objForEachKey, - objKeys, onConfigChange, openXhr, strTrim, strUndefined, useXDomainRequest + EventSendType, FullVersionString, IAppInsightsCore, ICookieMgr, IDiagnosticLogger, IExtendedConfiguration, IPayloadData, IPerfEvent, + IUnloadHook, IXHROverride, OnCompleteCallback, SendPOSTFunction, SendRequestReason, TransportType, _eExtendedInternalMessageId, + _eInternalMessageId, _throwInternal, _warnToConsole, arrForEach, dateNow, doPerf, dumpObj, eLoggingSeverity, extend, getLocation, + getNavigator, getTime, hasOwnProperty, isArray, isBeaconsSupported, isFetchSupported, isNullOrUndefined, isNumber, isReactNative, + isString, isUndefined, isValueAssigned, isXhrSupported, objForEachKey, objKeys, onConfigChange, openXhr, strTrim, strUndefined, + useXDomainRequest } from "@microsoft/1ds-core-js"; import { arrAppend } from "@nevware21/ts-utils"; import { BatchNotificationAction, BatchNotificationActions } from "./BatchNotificationActions"; import { ClockSkewManager } from "./ClockSkewManager"; import { - EventBatchNotificationReason, IChannelConfiguration, ICollectorResult, IPayloadData, IPostChannel, IPostTransmissionTelemetryItem, - IXHROverride, PayloadListenerFunction, PayloadPreprocessorFunction, SendPOSTFunction + EventBatchNotificationReason, IChannelConfiguration, ICollectorResult, IPostChannel, IPostTransmissionTelemetryItem, + PayloadListenerFunction, PayloadPreprocessorFunction } from "./DataModels"; import { EventBatch } from "./EventBatch"; import { @@ -77,7 +78,6 @@ _addCollectorHeaderQsMapping(STR_TIME_DELTA_TO_APPLY, STR_TIME_DELTA_TO_APPLY); _addCollectorHeaderQsMapping(STR_UPLOAD_TIME, STR_UPLOAD_TIME); _addCollectorHeaderQsMapping(STR_AUTH_XTOKEN, STR_AUTH_XTOKEN); -type OnCompleteCallback = (status: number, headers: { [headerName: string]: string }, response?: string) => void; function _getResponseText(xhr: XMLHttpRequest | IXDomainRequest) { try { diff --git a/channels/1ds-post-js/src/Index.ts b/channels/1ds-post-js/src/Index.ts index b5ed5ff2e..b1f8a71a3 100644 --- a/channels/1ds-post-js/src/Index.ts +++ b/channels/1ds-post-js/src/Index.ts @@ -5,14 +5,14 @@ * File to export public classes. */ +import { IPayloadData, IXHROverride, OnCompleteCallback, SendPOSTFunction } from "@microsoft/1ds-core-js"; import { - BE_PROFILE, IChannelConfiguration, IPayloadData, IPostChannel, IXHROverride, NRT_PROFILE, PayloadListenerFunction, - PayloadPreprocessorFunction, RT_PROFILE, SendPOSTFunction + BE_PROFILE, IChannelConfiguration, IPostChannel, NRT_PROFILE, PayloadListenerFunction, PayloadPreprocessorFunction, RT_PROFILE } from "./DataModels"; import { PostChannel } from "./PostChannel"; export { PostChannel, IChannelConfiguration, BE_PROFILE, NRT_PROFILE, RT_PROFILE, IXHROverride, IPostChannel, - SendPOSTFunction, IPayloadData, PayloadPreprocessorFunction, PayloadListenerFunction + SendPOSTFunction, IPayloadData, PayloadPreprocessorFunction, PayloadListenerFunction, OnCompleteCallback }; diff --git a/channels/1ds-post-js/test/Unit/src/HttpManagerTest.ts b/channels/1ds-post-js/test/Unit/src/HttpManagerTest.ts index fd80b6842..99c9c50e4 100644 --- a/channels/1ds-post-js/test/Unit/src/HttpManagerTest.ts +++ b/channels/1ds-post-js/test/Unit/src/HttpManagerTest.ts @@ -1,8 +1,8 @@ import { AITestClass } from "@microsoft/ai-test-framework"; import { HttpManager } from "../../../src/HttpManager"; import { AppInsightsCore, EventSendType, IExtendedConfiguration, SendRequestReason, TransportType, isBeaconsSupported } from "@microsoft/1ds-core-js"; -import { PostChannel, IXHROverride } from "../../../src/Index"; -import { IPostTransmissionTelemetryItem, IPayloadData, EventBatchNotificationReason, IChannelConfiguration } from "../../../src/DataModels"; +import { PostChannel, IXHROverride, IPayloadData } from "../../../src/Index"; +import { IPostTransmissionTelemetryItem, EventBatchNotificationReason, IChannelConfiguration } from "../../../src/DataModels"; import { EventBatch } from "../../../src/EventBatch"; interface EventDetail { diff --git a/channels/1ds-post-js/test/Unit/src/PostChannelTest.ts b/channels/1ds-post-js/test/Unit/src/PostChannelTest.ts index 747c40727..69b92bace 100644 --- a/channels/1ds-post-js/test/Unit/src/PostChannelTest.ts +++ b/channels/1ds-post-js/test/Unit/src/PostChannelTest.ts @@ -1,7 +1,7 @@ import { AITestClass } from "@microsoft/ai-test-framework"; import { IExtendedConfiguration, NotificationManager, AppInsightsCore, EventLatency, ITelemetryItem, IExtendedTelemetryItem, SendRequestReason, EventSendType, isFetchSupported, objKeys, arrForEach, isBeaconsSupported } from '@microsoft/1ds-core-js'; -import { PostChannel, IXHROverride, } from '../../../src/Index'; -import { IPostTransmissionTelemetryItem, IPayloadData, IChannelConfiguration } from '../../../src/DataModels'; +import { PostChannel, IXHROverride, IPayloadData } from '../../../src/Index'; +import { IPostTransmissionTelemetryItem, IChannelConfiguration } from '../../../src/DataModels'; import { SinonSpy } from 'sinon'; interface IEventsSendRequests { diff --git a/channels/1ds-post-js/test/Unit/src/SerializerTest.ts b/channels/1ds-post-js/test/Unit/src/SerializerTest.ts index b757628cb..77c41ce92 100644 --- a/channels/1ds-post-js/test/Unit/src/SerializerTest.ts +++ b/channels/1ds-post-js/test/Unit/src/SerializerTest.ts @@ -1,8 +1,8 @@ import { AITestClass } from "@microsoft/ai-test-framework"; import { HttpManager } from '../../../src/HttpManager'; import { AppInsightsCore, EventLatency, IEventProperty } from '@microsoft/1ds-core-js'; -import { PostChannel, IXHROverride } from '../../../src/Index'; -import { IPostTransmissionTelemetryItem, IPayloadData, EventBatchNotificationReason } from '../../../src/DataModels'; +import { PostChannel, IXHROverride, IPayloadData } from '../../../src/Index'; +import { IPostTransmissionTelemetryItem, EventBatchNotificationReason } from '../../../src/DataModels'; import { Serializer } from '../../../src/Serializer'; diff --git a/channels/applicationinsights-channel-js/Tests/Unit/src/Sender.tests.ts b/channels/applicationinsights-channel-js/Tests/Unit/src/Sender.tests.ts index 487052e2f..765bf4ca9 100644 --- a/channels/applicationinsights-channel-js/Tests/Unit/src/Sender.tests.ts +++ b/channels/applicationinsights-channel-js/Tests/Unit/src/Sender.tests.ts @@ -3,7 +3,7 @@ import { Sender } from "../../../src/Sender"; import { createOfflineListener, IOfflineListener } from '../../../src/Offline'; import { EnvelopeCreator } from '../../../src/EnvelopeCreator'; import { Exception, CtxTagKeys, isBeaconApiSupported, DEFAULT_BREEZE_ENDPOINT, DEFAULT_BREEZE_PATH, utlCanUseSessionStorage, utlGetSessionStorage, utlSetSessionStorage } from "@microsoft/applicationinsights-common"; -import { ITelemetryItem, AppInsightsCore, ITelemetryPlugin, DiagnosticLogger, NotificationManager, SendRequestReason, _eInternalMessageId, getGlobalInst, safeGetLogger, getJSON, isString, isArray, arrForEach, isBeaconsSupported } from "@microsoft/applicationinsights-core-js"; +import { ITelemetryItem, AppInsightsCore, ITelemetryPlugin, DiagnosticLogger, NotificationManager, SendRequestReason, _eInternalMessageId, getGlobalInst, safeGetLogger, getJSON, isString, isArray, arrForEach, isBeaconsSupported, IXHROverride, IPayloadData, isFetchSupported} from "@microsoft/applicationinsights-core-js"; import { ArraySendBuffer, SessionStorageSendBuffer } from "../../../src/SendBuffer"; import { ISenderConfig } from "../../../src/Interfaces"; @@ -118,6 +118,8 @@ export class SenderTests extends AITestClass { QUnit.assert.equal(undefined, defaultSenderConfig.customHeaders, "Channel default customHeaders config is set"); QUnit.assert.equal(undefined, defaultSenderConfig.convertUndefined, "Channel default convertUndefined config is set"); QUnit.assert.equal(10000, defaultSenderConfig.eventsLimitInMem, "Channel default eventsLimitInMem config is set"); + QUnit.assert.equal(undefined, defaultSenderConfig.httpXHROverride, "Channel default httpXHROverride config is set"); + QUnit.assert.equal(false, defaultSenderConfig.alwaysUseXhrOverride, "Channel default alwaysUseXhrOverride config is set"); //check dynamic config core.config.extensionConfig = core.config.extensionConfig? core.config.extensionConfig : {}; @@ -131,7 +133,8 @@ export class SenderTests extends AITestClass { isRetryDisabled: true, disableXhr: true, samplingPercentage: 90, - customHeaders: [{header: "header1",value:"value1"}] + customHeaders: [{header: "header1",value:"value1"}], + alwaysUseXhrOverride: true } core.config.extensionConfig[id] = config; this.clock.tick(1); @@ -145,6 +148,7 @@ export class SenderTests extends AITestClass { QUnit.assert.equal(true, curSenderConfig.isRetryDisabled, "Channel isRetryDisabled config is dynamically set"); QUnit.assert.equal(90, curSenderConfig.samplingPercentage, "Channel samplingPercentage config is dynamically set"); QUnit.assert.deepEqual([{header: "header1",value:"value1"}], curSenderConfig.customHeaders, "Channel customHeaders config is dynamically set"); + QUnit.assert.deepEqual(true, curSenderConfig.alwaysUseXhrOverride, "Channel alwaysUseXhrOverride config is dynamically set"); core.config.extensionConfig[this._sender.identifier].emitLineDelimitedJson = undefined; core.config.extensionConfig[this._sender.identifier].endpointUrl = undefined; @@ -154,6 +158,137 @@ export class SenderTests extends AITestClass { } }); + this.testCase({ + name: "Channel Config: Sender override can be handled correctly", + useFakeTimers: true, + test: () => { + let core = new AppInsightsCore(); + let sentPayloadData: any[] = []; + var xhrOverride: IXHROverride = { + sendPOST: (payload: IPayloadData, oncomplete: (status: number, headers: {[headerName: string]: string;}, response?: string) => void, sync?: boolean) => { + sentPayloadData.push({payload: payload, sync: sync}); + } + }; + + let coreConfig = { + instrumentationKey: "abc", + extensionConfig: { + [this._sender.identifier]: { + httpXHROverride: xhrOverride + } + } + } + let testBatch: string[] = ["test", "test1"]; + const telemetryItem: ITelemetryItem = { + name: "fake item", + iKey: "test", + baseType: "some type", + baseData: {} + }; + core.initialize(coreConfig, [this._sender]); + + // with always override to false + QUnit.assert.deepEqual(xhrOverride, this._sender._senderConfig.httpXHROverride, "Channel httpXHROverride config is set"); + QUnit.assert.deepEqual(false, this._sender._senderConfig.alwaysUseXhrOverride, "Channel alwaysUseXhrOverride config is set"); + this._sender._sender(testBatch, true); + QUnit.assert.equal(0, sentPayloadData.length, "httpXHROverride is not called once with always override to false"); + this._sender._sender(testBatch, false); + QUnit.assert.equal(0, sentPayloadData.length, "httpXHROverride is not called once with always override to false test1"); + + try { + this._sender.processTelemetry(telemetryItem); + } catch(e) { + QUnit.assert.ok(false, "Exception - " + e); + } + this._sender.onunloadFlush(); + QUnit.assert.deepEqual(0, sentPayloadData.length, "httpXHROverride should not be called again test2"); + + + // with always override to true + core.config.extensionConfig = core.config.extensionConfig || {}; + core.config.extensionConfig[this._sender.identifier].alwaysUseXhrOverride = true; + this.clock.tick(1); + QUnit.assert.deepEqual(true, this._sender._senderConfig.alwaysUseXhrOverride, "Channel alwaysUseXhrOverride config is set to true dynamically"); + this._sender._sender(testBatch, true); + QUnit.assert.deepEqual(1, sentPayloadData.length, "httpXHROverride should be called with always override to true"); + let payload = sentPayloadData[0].payload; + let sync = sentPayloadData[0].sync; + QUnit.assert.equal(false, sync, "Channel httpXHROverride sync is called with false during send test1 (sender interface should be opposite with the sender)"); + QUnit.assert.deepEqual(testBatch, payload.oriPayload, "Channel httpXHROverride sync is called with expected original payload"); + QUnit.assert.deepEqual(this._sender._buffer.batchPayloads(testBatch),payload.data, "Channel httpXHROverride sync is called with expected batch payload"); + + try { + this._sender.processTelemetry(telemetryItem); + } catch(e) { + QUnit.assert.ok(false, "Exception - " + e); + } + this._sender.onunloadFlush(); + QUnit.assert.deepEqual(2, sentPayloadData.length, "httpXHROverride should be called"); + let data = sentPayloadData[1].payload.oriPayload; + payload = JSON.parse(data[0]); + QUnit.assert.deepEqual("test", payload.iKey, "httpXHROverride should send expected payload test1"); + sync = sentPayloadData[1].sync; + QUnit.assert.equal(true, sync, "Channel httpXHROverride sync is called with true during send test2 (sender interface should be opposite with the sender)"); + + } + }); + + this.testCase({ + name: "Channel Config: Invalid paylod Sender should not be sent", + useFakeTimers: true, + test: () => { + let core = new AppInsightsCore(); + let sentPayloadData: any[] = []; + var xhrOverride: IXHROverride = { + sendPOST: (payload: IPayloadData, oncomplete: (status: number, headers: {[headerName: string]: string;}, response?: string) => void, sync?: boolean) => { + sentPayloadData.push({payload: payload, sync: sync}); + } + }; + + let coreConfig = { + instrumentationKey: "abc", + extensionConfig: { + [this._sender.identifier]: { + httpXHROverride: xhrOverride, + alwaysUseXhrOverride: true + } + } + } + let testBatch: string[] = ["test", "test1"]; + + core.initialize(coreConfig, [this._sender]); + + QUnit.assert.deepEqual(xhrOverride, this._sender._senderConfig.httpXHROverride, "Channel httpXHROverride config is set"); + QUnit.assert.deepEqual(true, this._sender._senderConfig.alwaysUseXhrOverride, "Channel alwaysUseXhrOverride config is set"); + // case 1: payload is null + this._sender._sender(null as any, true); + QUnit.assert.equal(0, sentPayloadData.length, "httpXHROverride is not called test1"); + this._sender._sender(null as any, false); + QUnit.assert.equal(0, sentPayloadData.length, "httpXHROverride is not called once sync test1"); + + // case 2: payload is none array + this._sender._sender({} as any, true); + QUnit.assert.equal(0, sentPayloadData.length, "httpXHROverride is not called test2"); + this._sender._sender({} as any, false); + QUnit.assert.equal(0, sentPayloadData.length, "httpXHROverride is not called once sync test2"); + + // case 3: payload is an empty array + this._sender._sender([] as any, true); + QUnit.assert.equal(0, sentPayloadData.length, "httpXHROverride is not called test3"); + this._sender._sender([] as any, false); + QUnit.assert.equal(0, sentPayloadData.length, "httpXHROverride is not called once sync test3"); + + + this._sender._sender(testBatch, true); + QUnit.assert.equal(1, sentPayloadData.length, "httpXHROverride is called test4"); + this._sender._sender(testBatch, false); + QUnit.assert.equal(2, sentPayloadData.length, "httpXHROverride is called once sync test4"); + + + } + }); + + this.testCase({ name: "Channel Config: sessionStorage change from true to false can be handled correctly", useFakeTimers: true, diff --git a/channels/applicationinsights-channel-js/src/Interfaces.ts b/channels/applicationinsights-channel-js/src/Interfaces.ts index 8f5d94fc1..fc88e2ce6 100644 --- a/channels/applicationinsights-channel-js/src/Interfaces.ts +++ b/channels/applicationinsights-channel-js/src/Interfaces.ts @@ -1,4 +1,5 @@ import { IStorageBuffer } from "@microsoft/applicationinsights-common"; +import { IXHROverride } from "@microsoft/applicationinsights-core-js"; export interface ISenderConfig { /** @@ -94,6 +95,26 @@ export interface ISenderConfig { * @since 3.0.1 */ enableSendPromise?: boolean; + + /** + * [Optional] The HTTP override that should be used to send requests, as an IXHROverride object. + * By default during the unload of a page or if the event specifies that it wants to use sendBeacon() or sync fetch (with keep-alive), + * this override will NOT be called. + * If alwaysUseXhrOverride configuration value is set to true, the override will always be used. + * The payload data (first argument) now also includes any configured 'timeout' (defaults to undefined) and whether you should avoid + * creating any synchronous XHR requests 'disableXhr' (defaults to false/undefined) + * @since 3.0.4 + */ + httpXHROverride?: IXHROverride; + + /** + * [Optional] By default during unload (or when you specify to use sendBeacon() or sync fetch (with keep-alive) for an event) the SDK + * ignores any provided httpXhrOverride and attempts to use sendBeacon() or fetch(with keep-alive) when they are available. + * When this configuration option is true any provided httpXhrOverride will always be used, so any provided httpXhrOverride will + * also need to "handle" the synchronous unload scenario. + * @since 3.0.4 + */ + alwaysUseXhrOverride?: boolean; } export interface IBackendResponse { diff --git a/channels/applicationinsights-channel-js/src/Sender.ts b/channels/applicationinsights-channel-js/src/Sender.ts index f18c940bc..f220fa014 100644 --- a/channels/applicationinsights-channel-js/src/Sender.ts +++ b/channels/applicationinsights-channel-js/src/Sender.ts @@ -6,19 +6,20 @@ import { } from "@microsoft/applicationinsights-common"; import { BaseTelemetryPlugin, IAppInsightsCore, IChannelControls, IConfigDefaults, IConfiguration, IDiagnosticLogger, INotificationManager, - IPlugin, IProcessTelemetryContext, IProcessTelemetryUnloadContext, ITelemetryItem, ITelemetryPluginChain, ITelemetryUnloadState, - SendRequestReason, _eInternalMessageId, _throwInternal, _warnToConsole, arrForEach, cfgDfBoolean, cfgDfValidate, - createProcessTelemetryContext, createUniqueNamespace, dateNow, dumpObj, eLoggingSeverity, getExceptionName, getIEVersion, getJSON, - getNavigator, getWindow, isArray, isBeaconsSupported, isFetchSupported, isNullOrUndefined, isXhrSupported, mergeEvtNamespace, objExtend, - objKeys, onConfigChange, runTargetUnload, useXDomainRequest + IPayloadData, IPlugin, IProcessTelemetryContext, IProcessTelemetryUnloadContext, ITelemetryItem, ITelemetryPluginChain, + ITelemetryUnloadState, IXHROverride, OnCompleteCallback, SendPOSTFunction, SendRequestReason, TransportType, _eInternalMessageId, + _throwInternal, _warnToConsole, arrForEach, cfgDfBoolean, cfgDfValidate, createProcessTelemetryContext, createUniqueNamespace, dateNow, + dumpObj, eLoggingSeverity, getExceptionName, getIEVersion, getJSON, getNavigator, getWindow, isArray, isBeaconsSupported, + isFetchSupported, isNullOrUndefined, isXhrSupported, mergeEvtNamespace, objExtend, objKeys, onConfigChange, runTargetUnload, + useXDomainRequest } from "@microsoft/applicationinsights-core-js"; import { IPromise, createPromise, doAwaitResponse } from "@nevware21/ts-async"; -import { ITimerHandler, isTruthy, objDeepFreeze, objDefine, scheduleTimeout } from "@nevware21/ts-utils"; +import { ITimerHandler, isString, isTruthy, objDeepFreeze, objDefine, scheduleTimeout } from "@nevware21/ts-utils"; import { DependencyEnvelopeCreator, EventEnvelopeCreator, ExceptionEnvelopeCreator, MetricEnvelopeCreator, PageViewEnvelopeCreator, PageViewPerformanceEnvelopeCreator, TraceEnvelopeCreator } from "./EnvelopeCreator"; -import { IBackendResponse, ISenderConfig, XDomainRequest as IXDomainRequest } from "./Interfaces"; +import { IBackendResponse, ISenderConfig, XDomainRequest, XDomainRequest as IXDomainRequest } from "./Interfaces"; import { IOfflineListener, createOfflineListener } from "./Offline"; import { ArraySendBuffer, ISendBuffer, SessionStorageSendBuffer } from "./SendBuffer"; import { Serializer } from "./Serializer"; @@ -33,7 +34,10 @@ declare var XDomainRequest: { new(): IXDomainRequest; }; -export type SenderFunction = (payload: string[], isAsync: boolean) => void | IPromise; +interface IInternalPayloadData extends IPayloadData { + oriPayload: string[]; +} + function _getResponseText(xhr: XMLHttpRequest | IXDomainRequest) { try { @@ -45,6 +49,10 @@ function _getResponseText(xhr: XMLHttpRequest | IXDomainRequest) { return null; } +function isOverrideFn(httpXHROverride: any) { + return httpXHROverride && httpXHROverride.sendPOST; +} + const defaultAppInsightsChannelConfig: IConfigDefaults = objDeepFreeze({ // Use the default value (handles empty string in the configuration) endpointUrl: cfgDfValidate(isTruthy, DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH), @@ -64,7 +72,9 @@ const defaultAppInsightsChannelConfig: IConfigDefaults = objDeepF customHeaders: UNDEFINED_VALUE, convertUndefined: UNDEFINED_VALUE, eventsLimitInMem: 10000, - bufferOverride: false + bufferOverride: false, + httpXHROverride: { isVal: isOverrideFn, v:UNDEFINED_VALUE }, + alwaysUseXhrOverride: cfgDfBoolean() }); function _chkSampling(value: number) { @@ -83,6 +93,8 @@ const EnvelopeTypeCreator: { [key:string] : EnvelopeCreator } = { [RemoteDependencyData.dataType]: DependencyEnvelopeCreator }; +export type SenderFunction = (payload: string[], isAsync: boolean) => void | IPromise; + export class Sender extends BaseTelemetryPlugin implements IChannelControls { public static constructEnvelope(orig: ITelemetryItem, iKey: string, logger: IDiagnosticLogger, convertUndefined?: any): IEnvelope { @@ -140,7 +152,6 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { let _stamp_specific_redirects: number; let _headers: { [name: string]: string }; let _syncFetchPayload = 0; // Keep track of the outstanding sync fetch payload total (as sync fetch has limits) - let _fallbackSender: SenderFunction; // The sender to use if the payload size is too large let _syncUnloadSender: SenderFunction; // The identified sender to use for the synchronous unload stage let _offlineListener: IOfflineListener; let _evtNamespace: string | string[]; @@ -158,6 +169,10 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { let _bufferOverrideUsed: IStorageBuffer | false; let _namePrefix: string; let _enableSendPromise: boolean; + let _alwaysUseCustomSend: boolean; + let _disableXhr: boolean; + let _fetchKeepAlive: boolean; + let _xhrSend: SenderFunction; dynamicProto(Sender, this, (_self, _base) => { @@ -197,7 +212,7 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { _self.onunloadFlush = () => { if (!_paused) { - if (_beaconSupported) { + if (_beaconSupported || _alwaysUseCustomSend) { try { return _self.triggerSend(true, _doUnloadSend, SendRequestReason.Unload); } catch (e) { @@ -266,6 +281,8 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { _maxBatchSizeInBytes = senderConfig.maxBatchSizeInBytes; _beaconSupported = (senderConfig.onunloadDisableBeacon === false || senderConfig.isBeaconApiDisabled === false) && isBeaconsSupported(); + _alwaysUseCustomSend = senderConfig.alwaysUseXhrOverride; + _disableXhr = !!senderConfig.disableXhr; let bufferOverride = senderConfig.bufferOverride; let canUseSessionStorage = !!senderConfig.enableSessionStorageBuffer && @@ -307,6 +324,7 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { _namePrefix = namePrefix; _sessionStorageUsed = canUseSessionStorage; _bufferOverrideUsed = bufferOverride; + _fetchKeepAlive = !senderConfig.onunloadDisableFetch && isFetchSupported(true); _self._sample = new Sample(senderConfig.samplingPercentage, diagLog); @@ -325,42 +343,44 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { } else { _customHeaders = null; } - _enableSendPromise = senderConfig.enableSendPromise; - let sendPostFunc: SenderFunction = null; - if (!senderConfig.disableXhr && useXDomainRequest()) { - sendPostFunc = _xdrSender; // IE 8 and 9 - } else if (!senderConfig.disableXhr && isXhrSupported()) { - sendPostFunc = _xhrSender; - } - - if (!sendPostFunc && isFetchSupported()) { - sendPostFunc = _fetchSender; - } + let customInterface = senderConfig.httpXHROverride; + let httpInterface: IXHROverride = null; + let syncInterface: IXHROverride = null; + httpInterface = _getSenderInterface([TransportType.Xhr, TransportType.Fetch], false); + + let xhrInterface = { sendPOST: _xhrSender} as IXHROverride; + _xhrSend = (payload: string[], isAsync: boolean) => { + return _doSend(xhrInterface, payload, isAsync); + }; - // always fallback to XHR - _fallbackSender = sendPostFunc || _xhrSender; if (!senderConfig.isBeaconApiDisabled && isBeaconsSupported()) { // Config is set to always used beacon sending - sendPostFunc = _beaconSender; + httpInterface = _getSenderInterface([TransportType.Beacon], false); } + + httpInterface = _alwaysUseCustomSend? customInterface : (httpInterface || customInterface || xhrInterface); - _self._sender = sendPostFunc || _xhrSender; - - if (!senderConfig.onunloadDisableFetch && isFetchSupported(true)) { + _self._sender = (payload: string[], isAsync: boolean) => { + return _doSend(httpInterface, payload, isAsync); + }; + + if (_fetchKeepAlive) { // Try and use the fetch with keepalive _syncUnloadSender = _fetchKeepAliveSender; - } else if (isBeaconsSupported()) { - // Try and use sendBeacon - _syncUnloadSender = _beaconSender; - } else if (!senderConfig.disableXhr && useXDomainRequest()) { - _syncUnloadSender = _xdrSender; // IE 8 and 9 - } else if (!senderConfig.disableXhr && isXhrSupported()) { - _syncUnloadSender = _xhrSender; - } else { - _syncUnloadSender = _fallbackSender; + } + syncInterface = _alwaysUseCustomSend? customInterface : (_getSenderInterface([TransportType.Beacon, TransportType.Xhr], true) || customInterface); + + if ((_alwaysUseCustomSend || !_syncUnloadSender) && syncInterface) { + _syncUnloadSender = (payload: string[], isAsync: boolean) => { + return _doSend(syncInterface, payload, isAsync); + }; + } + + if (!_syncUnloadSender) { + _syncUnloadSender = _xhrSend; } _disableTelemetry = senderConfig.disableTelemetry; @@ -479,7 +499,7 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { if (xhr.readyState === 4) { _checkResponsStatus(xhr.status, payload, xhr.responseURL, countOfItemsInPayload, _formatErrorMessageXhr(xhr), _getResponseText(xhr) || xhr.response); } - }; + } /** * Immediately send buffered data @@ -613,12 +633,97 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { _self._onError(payload, _formatErrorMessageXdr(xdr)); } } - }; + + } function _isSampledIn(envelope: ITelemetryItem): boolean { return _self._sample.isSampledIn(envelope); } + function _getSenderInterface(transports: TransportType[], syncSupport: boolean): IXHROverride { + let transportType: TransportType = null; + let sendPostFunc: SendPOSTFunction = null; + let lp = 0; + while (sendPostFunc == null && lp < transports.length) { + transportType = transports[lp]; + if (!_disableXhr && transportType === TransportType.Xhr) { + if (useXDomainRequest()) { + // IE 8 and 9 + sendPostFunc = _xdrSender; + } else if (isXhrSupported()) { + sendPostFunc = _xhrSender; + } + } else if (transportType === TransportType.Fetch && isFetchSupported(syncSupport)) { + sendPostFunc = _fetchSender; + } else if (isBeaconsSupported() && transportType === TransportType.Beacon) { + sendPostFunc = _beaconSender; + } + + lp++; + } + + if (sendPostFunc) { + return { + sendPOST: sendPostFunc + }; + } + + return null; + } + + function _getOnComplete(payload: string[], status: number, headers: {[headerName: string]: string;}, response?: string) { + + // *********************************************************************************************** + //TODO: handle other status codes + if (status === 200 && payload) { + _self._onSuccess(payload, payload.length); + } + response && _self._onError(payload, response); + } + + function _doSend(sendInterface: IXHROverride, payload: string[], isAsync: boolean): void | IPromise { + let onComplete = (status: number, headers: {[headerName: string]: string;}, response?: string) => { + return _getOnComplete(payload, status, headers, response); + } + let payloadData = _getPayload(payload); + + let sendPostFunc: SendPOSTFunction = sendInterface && sendInterface.sendPOST; + if (sendPostFunc && payloadData) { + // *********************************************************************************************** + // mark payload as sent at the beginning of calling each send function + _self._buffer.markAsSent(payload); + return sendPostFunc(payloadData, onComplete, !isAsync); + } + return null; + } + + function _getPayload(payload: string[]): IInternalPayloadData { + if (isArray(payload) && payload.length > 0) { + let batch = _self._buffer.batchPayloads(payload); + let payloadData: IInternalPayloadData = { + data: batch, + urlString: _endpointUrl, + headers: _headers, + disableXhrSync: _disableXhr, + disableFetchKeepAlive: !_fetchKeepAlive, + oriPayload: payload + }; + return payloadData; + } + + return null; + } + + /** + * Send fetch API request + * @param payload - {string} - The data payload to be sent. + * @param oncomplete - {function} on complete function + * @param sync - {boolean} - not used + */ + function _fetchSender(payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) { + return _doFetchSender(payload, oncomplete, false); + } + function _checkMaxSize(incomingPayload?: string): boolean { let incomingSize = incomingPayload? incomingPayload.length : 0; if ((_self._buffer.size() + incomingSize) > _maxBatchSizeInBytes) { @@ -709,61 +814,77 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { } return false; } + + function _doOnComplete(oncomplete: OnCompleteCallback, status: number, headers: { [headerName: string]: string }, response?: string) { + try { + oncomplete(status, headers, response); + } catch (e) { + // eslint-disable-next-line no-empty + } + } function _doUnloadSend(payload: string[], isAsync: boolean) { + let onComplete = (status: number, headers: {[headerName: string]: string;}, response?: string) => { + return _getOnComplete(payload, status, headers, response); + } if (_syncUnloadSender) { // We are unloading so always call the sender with sync set to false _syncUnloadSender(payload, false); } else { // Fallback to the previous beacon Sender (which causes a CORB warning on chrome now) - _beaconSender(payload, isAsync); + let payloadData = _getPayload(payload) + _beaconSender(payloadData, onComplete, !isAsync); } } - function _doBeaconSend(payload: string[]) { + + function _doBeaconSend(payload: string, oncomplete?: OnCompleteCallback) { const nav = getNavigator(); - const buffer = _self._buffer; const url = _endpointUrl; - const batch = _self._buffer.batchPayloads(payload); // Chrome only allows CORS-safelisted values for the sendBeacon data argument // see: https://bugs.chromium.org/p/chromium/issues/detail?id=720283 - const plainTextBatch = new Blob([batch], { type: "text/plain;charset=UTF-8" }); + const plainTextBatch = new Blob([payload], { type: "text/plain;charset=UTF-8" }); // The sendBeacon method returns true if the user agent is able to successfully queue the data for transfer. Otherwise it returns false. const queued = nav.sendBeacon(url, plainTextBatch); if (queued) { - buffer.markAsSent(payload); - // no response from beaconSender, clear buffer - _self._onSuccess(payload, payload.length); + oncomplete(200, {}, payload) } return queued; } + /** * Send Beacon API request * @param payload - {string} - The data payload to be sent. - * @param isAsync - {boolean} - not used + * @param sync - {boolean} - not used * Note: Beacon API does not support custom headers and we are not able to get * appId from the backend for the correct correlation. */ - function _beaconSender(payload: string[], isAsync: boolean) { - if (isArray(payload) && payload.length > 0) { + function _beaconSender(payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) { + let internalPayload = payload as IInternalPayloadData; + let data = internalPayload && internalPayload.data; + if (isString(data) && data.length > 0) { // The sendBeacon method returns true if the user agent is able to successfully queue the data for transfer. Otherwise it returns false. - if (!_doBeaconSend(payload)) { + if (!_doBeaconSend(data, oncomplete)) { // Failed to send entire payload so try and split data and try to send as much events as possible let droppedPayload: string[] = []; - for (let lp = 0; lp < payload.length; lp++) { - const thePayload = payload[lp]; - - if (!_doBeaconSend([thePayload])) { - // Can't send anymore, so split the batch and drop the rest - droppedPayload.push(thePayload); + let oriPayload = internalPayload.oriPayload; + if (oriPayload.length > 0) { + for (let lp = 0; lp < data.length; lp++) { + const thePayload = payload[lp]; + const batch = _self._buffer.batchPayloads(thePayload); + + if (!_doBeaconSend(batch, oncomplete)) { + // Can't send anymore, so split the batch and drop the rest + droppedPayload.push(thePayload); + } } } if (droppedPayload.length > 0) { - _fallbackSender && _fallbackSender(droppedPayload, true); + _xhrSend && _xhrSend(droppedPayload, true); _throwInternal(_self.diagLog(), eLoggingSeverity.WARNING, _eInternalMessageId.TransmissionFailed, ". " + "Failed to send telemetry with Beacon API, retried with normal sender."); } } @@ -773,9 +894,10 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { /** * Send XMLHttpRequest * @param payload - {string} - The data payload to be sent. - * @param isAsync - {boolean} - Indicates if the request should be sent asynchronously + * @param sync - {boolean} - Indicates if the request should be sent synchronously */ - function _xhrSender(payload: string[], isAsync: boolean): void | IPromise { + function _xhrSender(payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean): void | IPromise { + let internalPayload = payload as IInternalPayloadData; let thePromise: void | IPromise; let resolveFunc: (sendComplete: boolean) => void; let rejectFunc: (reason?: any) => void; @@ -788,7 +910,7 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { // If the environment has locked down the XMLHttpRequest (preventExtensions and/or freeze), this would // cause the request to fail and we no telemetry would be sent } - xhr.open("POST", endPointUrl, isAsync); + xhr.open("POST", endPointUrl, !sync); xhr.setRequestHeader("Content-type", "application/json"); // append Sdk-Context request header only in case of breeze endpoint @@ -801,47 +923,51 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { }); xhr.onreadystatechange = () => { - _self._xhrReadyStateChange(xhr, payload, payload.length); + let oriPayload = internalPayload.oriPayload; + _self._xhrReadyStateChange(xhr, oriPayload, oriPayload.length); if (xhr.readyState === 4) { resolveFunc && resolveFunc(true); } } + xhr.onerror = (event: ErrorEvent|any) => { - _self._onError(payload, _formatErrorMessageXhr(xhr), event); + _doOnComplete(oncomplete, 400, {}, _formatErrorMessageXhr(xhr)); rejectFunc && rejectFunc(event); } - if (isAsync && _enableSendPromise) { + if (!sync && _enableSendPromise) { thePromise = createPromise((resolve, reject) => { resolveFunc = resolve; rejectFunc = reject; }); } - // compose an array of payloads - const batch = _self._buffer.batchPayloads(payload); - xhr.send(batch); - - _self._buffer.markAsSent(payload); + + xhr.send(payload.data); return thePromise; } + function _fetchKeepAliveSender(payload: string[], isAsync: boolean) { + let onComplete = (status: number, headers: {[headerName: string]: string;}, response?: string) => { + return _getOnComplete(payload, status, headers, response); + } if (isArray(payload)) { let payloadSize = payload.length; for (let lp = 0; lp < payload.length; lp++) { payloadSize += payload[lp].length; } + let payloadData = _getPayload(payload); if ((_syncFetchPayload + payloadSize) <= FetchSyncRequestSizeLimitBytes) { - _doFetchSender(payload, false); + _doFetchSender(payloadData, onComplete, true); } else if (isBeaconsSupported()) { // Fallback to beacon sender as we at least get told which events can't be scheduled - _beaconSender(payload, isAsync); + _beaconSender(payloadData, onComplete, !isAsync); } else { // Payload is going to be too big so just try and send via XHR - _fallbackSender && _fallbackSender(payload, true); + _xhrSend && _xhrSend(payload, true); _throwInternal(_self.diagLog(), eLoggingSeverity.WARNING, _eInternalMessageId.TransmissionFailed, ". " + "Failed to send telemetry with Beacon API, retried with xhrSender."); } } @@ -850,20 +976,12 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { /** * Send fetch API request * @param payload - {string} - The data payload to be sent. - * @param isAsync - {boolean} - not used + * @param sync - {boolean} - For fetch this identifies whether we are "unloading" (false) or a normal request */ - function _fetchSender(payload: string[], isAsync: boolean) { - return _doFetchSender(payload, true); - } - - /** - * Send fetch API request - * @param payload - {string} - The data payload to be sent. - * @param isAsync - {boolean} - For fetch this identifies whether we are "unloading" (false) or a normal request - */ - function _doFetchSender(payload: string[], isAsync: boolean): void | IPromise { + function _doFetchSender(payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean): void | IPromise { const endPointUrl = _endpointUrl; - const batch = _self._buffer.batchPayloads(payload); + let internalPayload = payload as IInternalPayloadData; + const batch = internalPayload.data; const plainTextBatch = new Blob([batch], { type: "application/json" }); let thePromise: void | IPromise; let resolveFunc: (sendComplete: boolean) => void; @@ -889,7 +1007,7 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { [DisabledPropertyName]: true // Mark so we don't attempt to track this request }; - if (!isAsync) { + if (sync) { init.keepalive = true; // As a sync request (during unload), it is unlikely that we will get a chance to process the response so // just like beacon send assume that the events have been accepted and processed @@ -906,9 +1024,7 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { // cause the request to fail and we no telemetry would be sent } - _self._buffer.markAsSent(payload); - - if (isAsync && _enableSendPromise) { + if (!sync && _enableSendPromise) { thePromise = createPromise((resolve, reject) => { resolveFunc = resolve; rejectFunc = reject; @@ -916,7 +1032,7 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { } try { doAwaitResponse(fetch(request), (result) => { - if (!isAsync) { + if (sync) { _syncFetchPayload -= batchLength; batchLength = 0; } @@ -933,23 +1049,25 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { * or if anything prevented the request from completing. */ if (!response.ok) { - _self._onError(payload, response.statusText); + _doOnComplete(oncomplete, 400, {}, response.statusText); + resolveFunc && resolveFunc(false); } else { doAwaitResponse(response.text(), (resp) => { - _checkResponsStatus(response.status, payload, response.url, payload.length, response.statusText, resp.value || ""); + let oriPayload = internalPayload.oriPayload; + _checkResponsStatus(response.status, oriPayload, response.url, oriPayload.length, response.statusText, resp.value || ""); resolveFunc && resolveFunc(true); }); } } else { - _self._onError(payload, result.reason && result.reason.message); + _doOnComplete(oncomplete, 400, {}, result.reason && result.reason.message); rejectFunc && rejectFunc(result.reason); } } }); } catch (e) { if (!responseHandled) { - _self._onError(payload, dumpObj(e)); + _doOnComplete(oncomplete, 400, {}, dumpObj(e)); rejectFunc && rejectFunc(e); } } @@ -957,12 +1075,13 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { if (ignoreResponse && !responseHandled) { // Assume success during unload processing as we most likely won't get the response responseHandled = true; - _self._onSuccess(payload, payload.length); + _doOnComplete(oncomplete, 200, {}); resolveFunc && resolveFunc(true); } return thePromise; } + /** * Parses the response from the backend. @@ -1085,20 +1204,28 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { /** * Send XDomainRequest * @param payload - {string} - The data payload to be sent. - * @param isAsync - {boolean} - Indicates if the request should be sent asynchronously + * @param sync - {boolean} - Indicates if the request should be sent synchronously * * Note: XDomainRequest does not support sync requests. This 'isAsync' parameter is added * to maintain consistency with the xhrSender's contract * Note: XDomainRequest does not support custom headers and we are not able to get * appId from the backend for the correct correlation. */ - function _xdrSender(payload: string[], isAsync: boolean) { - const buffer = _self._buffer; + function _xdrSender(payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) { + let internalPayload = payload as IInternalPayloadData; let _window = getWindow(); const xdr = new XDomainRequest(); + let data = internalPayload.data; // NOTE: xdr may send previous retry payload to new endpoint since we are not able to check response URL - xdr.onload = () => _self._xdrOnLoad(xdr, payload); - xdr.onerror = (event: ErrorEvent|any) => _self._onError(payload, _formatErrorMessageXdr(xdr), event); + xdr.onload = () => { + let oriPayload = internalPayload.oriPayload; + // we will assume onload means the request succeeded. + _self._xdrOnLoad(xdr, oriPayload); + }; + + xdr.onerror = () => { + _doOnComplete(oncomplete, 400, {}, _formatErrorMessageXdr(xdr)); + }; // XDomainRequest requires the same protocol as the hosting page. // If the protocol doesn't match, we can't send the telemetry :(. @@ -1109,18 +1236,15 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { _eInternalMessageId.TransmissionFailed, ". " + "Cannot send XDomain request. The endpoint URL protocol doesn't match the hosting page protocol."); - buffer.clear(); + _self._buffer.clear(); return; } const endpointUrl = _endpointUrl.replace(/^(https?:)/, ""); xdr.open("POST", endpointUrl); - // compose an array of payloads - const batch = buffer.batchPayloads(payload); - xdr.send(batch); - - buffer.markAsSent(payload); + xdr.send(data as any); + } function _formatErrorMessageXdr(xdr: IXDomainRequest, message?: string): string { @@ -1187,7 +1311,6 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { _serializer = null; _stamp_specific_redirects = 0; _syncFetchPayload = 0; - _fallbackSender = null; _syncUnloadSender = null; _evtNamespace = null; _endpointUrl = null; @@ -1201,6 +1324,9 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { _isRetryDisabled = false; _sessionStorageUsed = null; _namePrefix = UNDEFINED_VALUE; + _disableXhr = false; + _fetchKeepAlive = false; + _xhrSend = null; objDefine(_self, "_senderConfig", { g: function() { @@ -1266,6 +1392,7 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { /** * xhr state changes + * @deprecated */ public _xhrReadyStateChange(xhr: XMLHttpRequest, payload: string[], countOfItemsInPayload: number) { // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging @@ -1309,6 +1436,7 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls { /** * xdr state changes + * @deprecated */ public _xdrOnLoad(xdr: IXDomainRequest, payload: string[]) { // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging diff --git a/channels/applicationinsights-channel-js/src/applicationinsights-channel-js.ts b/channels/applicationinsights-channel-js/src/applicationinsights-channel-js.ts index 01f58b6c9..dc43ff393 100644 --- a/channels/applicationinsights-channel-js/src/applicationinsights-channel-js.ts +++ b/channels/applicationinsights-channel-js/src/applicationinsights-channel-js.ts @@ -1 +1 @@ -export { Sender } from "./Sender"; \ No newline at end of file +export { Sender } from "./Sender"; diff --git a/common/config/rush/npm-shrinkwrap.json b/common/config/rush/npm-shrinkwrap.json index 0276f32fd..2eb5831e8 100644 --- a/common/config/rush/npm-shrinkwrap.json +++ b/common/config/rush/npm-shrinkwrap.json @@ -204,9 +204,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz", - "integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.2.tgz", + "integrity": "sha512-0MGxAVt1m/ZK+LTJp/j0qF7Hz97D9O/FH9Ms3ltnyIdDD57cbb1ACIQTkbHvNXtWDv5TPq7w5Kq56+cNukbo7g==", "peer": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -236,9 +236,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", - "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", + "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -283,16 +283,16 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@microsoft/api-extractor": { - "version": "7.37.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.37.0.tgz", - "integrity": "sha512-df/wffWpDhYRw7kzdxeHGsCpim+dC8aFiZlsJb4uFvVPWhBZpDzOhQxSUTFx3Df1ORY+/JjuPR3fDE9Hq+PHzQ==", + "version": "7.37.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.37.1.tgz", + "integrity": "sha512-wbTL7TZG+9SPvYKwk26390ltoP/uR5621dniqhVp+5OHcn7wIKsT7vX9d/wvdAXD3Ft+7pAiCt6y3dBLFfY/0w==", "dependencies": { - "@microsoft/api-extractor-model": "7.28.0", + "@microsoft/api-extractor-model": "7.28.1", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.60.0", - "@rushstack/rig-package": "0.5.0", - "@rushstack/ts-command-line": "4.16.0", + "@rushstack/node-core-library": "3.60.1", + "@rushstack/rig-package": "0.5.1", + "@rushstack/ts-command-line": "4.16.1", "colors": "~1.2.1", "lodash": "~4.17.15", "resolve": "~1.22.1", @@ -305,13 +305,13 @@ } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.0.tgz", - "integrity": "sha512-QIMtUVm1tqiKG+M6ciFgRShcDoovyltaeg+CbyOnyr7SMrp6gg0ojK5/nToMqR9kAvsTS4QVgW4Twl50EoAjcw==", + "version": "7.28.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.1.tgz", + "integrity": "sha512-1hD9gQRu8VR53/e8GI+aql7MtWXHE/XtpOSgphJ6SB7AswqJT0mRZVufUbg3D57UdrchvLKz9b+zqay0Oq2vgg==", "dependencies": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.60.0" + "@rushstack/node-core-library": "3.60.1" } }, "node_modules/@microsoft/api-extractor/node_modules/typescript": { @@ -1211,9 +1211,9 @@ } }, "node_modules/@rushstack/node-core-library": { - "version": "3.60.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.60.0.tgz", - "integrity": "sha512-PcyrqhILvzU+65wMFybQ2VeGNnU5JzhDq2OvUi3j6jPUxyllM7b2hrRUwCuVaYboewYzIbpzXFzgxe2K7ii1nw==", + "version": "3.60.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.60.1.tgz", + "integrity": "sha512-cWKCImfezPvILKu5eUPkz0Mp/cO/zOSJdPD64KHliBcdmbPHg/sF4rEL7WJkWywXT1RQ/U/N8uKdXMe7jDCXNw==", "dependencies": { "colors": "~1.2.1", "fs-extra": "~7.0.1", @@ -1233,18 +1233,18 @@ } }, "node_modules/@rushstack/rig-package": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.0.tgz", - "integrity": "sha512-bGnOW4DWHOePDiABKy6qyqYJl9i7fKn4bRucExRVt5QzyPxuVHMl8CMmCabtoNSpXzgG3qymWOrMoa/W2PpJrw==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.1.tgz", + "integrity": "sha512-pXRYSe29TjRw7rqxD4WS3HN/sRSbfr+tJs4a9uuaSIBAITbUggygdhuG0VrO0EO+QqH91GhYMN4S6KRtOEmGVA==", "dependencies": { "resolve": "~1.22.1", "strip-json-comments": "~3.1.1" } }, "node_modules/@rushstack/ts-command-line": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.16.0.tgz", - "integrity": "sha512-WJKhdR9ThK9Iy7t78O3at7I3X4Ssp5RRZay/IQa8NywqkFy/DQbT3iLouodMMdUwLZD9n8n++xLubVd3dkmpkg==", + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.16.1.tgz", + "integrity": "sha512-+OCsD553GYVLEmz12yiFjMOzuPeCiZ3f8wTiFHL30ZVXexTyPmgjwXEhg2K2P0a2lVf+8YBy7WtPoflB2Fp8/A==", "dependencies": { "@types/argparse": "1.0.38", "argparse": "~1.0.9", @@ -1332,9 +1332,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.2.tgz", + "integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==" }, "node_modules/@types/file-saver": { "version": "2.0.5", @@ -1396,9 +1396,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.14.198", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz", - "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==" + "version": "4.14.199", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.199.tgz", + "integrity": "sha512-Vrjz5N5Ia4SEzWWgIVwnHNEnb1UE1XMkvY5DGXrAeOGE9imk0hgTHh5GyDjLDJi9OTCn9oo9dXH1uToK1VRfrg==" }, "node_modules/@types/minimatch": { "version": "5.1.2", @@ -1416,9 +1416,9 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "node_modules/@types/prop-types": { - "version": "15.7.6", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.6.tgz", - "integrity": "sha512-RK/kBbYOQQHLYj9Z95eh7S6t7gq4Ojt/NT8HTk8bWVhA5DaF+5SMnxHKkP4gPNN3wAZkKP+VjAf0ebtYzf+fxg==" + "version": "15.7.7", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.7.tgz", + "integrity": "sha512-FbtmBWCcSa2J4zL781Zf1p5YUBXQomPEcep9QZCfRfQgTxz3pJWiDFLebohZ9fFntX5ibzOkSsrJ0TEew8cAog==" }, "node_modules/@types/qunit": { "version": "2.19.6", @@ -1426,9 +1426,9 @@ "integrity": "sha512-bz9STa6EHurtpSfn5cNiScBladlw43bM+7luQA985Kd9YlF4dZaLmKt3c5/oSyN1AWAl50YBpqTq0BxCP64nGg==" }, "node_modules/@types/react": { - "version": "16.14.46", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.46.tgz", - "integrity": "sha512-Am4pyXMrr6cWWw/TN3oqHtEZl0j+G6Up/O8m65+xF/3ZaUgkv1GAtTPWw4yNRmH0HJXmur6xKCKoMo3rBGynuw==", + "version": "16.14.47", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.47.tgz", + "integrity": "sha512-m0EmmY73mbQegA+aqo0+O/hHU9iTi+hNYotJ3cM4sLFox8NqZv3XVXQhhqpd3YH6YC7h+YIyJFd36O5KlaJLCA==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -1457,14 +1457,14 @@ } }, "node_modules/@types/scheduler": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", - "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" + "version": "0.16.4", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.4.tgz", + "integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==" }, "node_modules/@types/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", "peer": true }, "node_modules/@types/sinon": { @@ -1473,25 +1473,25 @@ "integrity": "sha512-Tt7w/ylBS/OEAlSCwzB0Db1KbxnkycP/1UkQpbvKFYoUuRn4uYsC3xh5TRPrOjTy0i8TIkSz1JdNL4GPVdf3KQ==" }, "node_modules/@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.1.tgz", + "integrity": "sha512-CHzgNU3qYBnp/O4S3yv2tXPlvMTq0YWSTVg2/JYLqWZGHwwgJGAwd00poay/11asPq8wLFwHzubyInqHIFmmiw==", "optional": true, "dependencies": { "@types/node": "*" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.2.tgz", - "integrity": "sha512-ooaHxlmSgZTM6CHYAFRlifqh1OAr3PAQEwi7lhYhaegbnXrnh7CDcHmc3+ihhbQC7H0i4JF0psI5ehzkF6Yl6Q==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz", + "integrity": "sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA==", "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/type-utils": "6.7.2", - "@typescript-eslint/utils": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/type-utils": "6.7.3", + "@typescript-eslint/utils": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1517,15 +1517,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.2.tgz", - "integrity": "sha512-KA3E4ox0ws+SPyxQf9iSI25R6b4Ne78ORhNHeVKrPQnoYsb9UhieoiRoJgrzgEeKGOXhcY1i8YtOeCHHTDa6Fw==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", + "integrity": "sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==", "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/typescript-estree": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4" }, "engines": { @@ -1545,13 +1545,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz", - "integrity": "sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", + "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", "peer": true, "dependencies": { - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2" + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1562,13 +1562,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.2.tgz", - "integrity": "sha512-36F4fOYIROYRl0qj95dYKx6kybddLtsbmPIYNK0OBeXv2j9L5nZ17j9jmfy+bIDHKQgn2EZX+cofsqi8NPATBQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.3.tgz", + "integrity": "sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw==", "peer": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.2", - "@typescript-eslint/utils": "6.7.2", + "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/utils": "6.7.3", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -1589,9 +1589,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz", - "integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", + "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", "peer": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1602,13 +1602,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz", - "integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", + "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", "peer": true, "dependencies": { - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1629,17 +1629,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.2.tgz", - "integrity": "sha512-ZCcBJug/TS6fXRTsoTkgnsvyWSiXwMNiPzBUani7hDidBdj1779qwM1FIAmpH4lvlOZNF3EScsxxuGifjpLSWQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.3.tgz", + "integrity": "sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg==", "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/typescript-estree": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.3", "semver": "^7.5.4" }, "engines": { @@ -1654,12 +1654,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz", - "integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", + "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", "peer": true, "dependencies": { - "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/types": "6.7.3", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -1956,9 +1956,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "version": "4.21.11", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.11.tgz", + "integrity": "sha512-xn1UXOKUz7DjdGlg9RrUr0GGiWzI97UQJnugHtH0OLDfJB7jMgoIkYvRIEO1l9EeEERVqeqLYOcFBW9ldjypbQ==", "funding": [ { "type": "opencollective", @@ -1974,10 +1974,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", + "caniuse-lite": "^1.0.30001538", + "electron-to-chromium": "^1.4.526", "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -2075,9 +2075,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001538", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001538.tgz", - "integrity": "sha512-HWJnhnID+0YMtGlzcp3T9drmBJUVDchPJ08tpUGFLs9CYlwWPH2uLgpHn8fND5pCgXVtnGS3H4QR9XLMHVNkHw==", + "version": "1.0.30001539", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001539.tgz", + "integrity": "sha512-hfS5tE8bnNiNvEOEkm8HElUHroYwlqMMENEzELymy77+tJ6m+gA2krtHl5hxJaj71OlpC2cHZbdSMX1/YEqEkA==", "funding": [ { "type": "opencollective", @@ -2460,9 +2460,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.524", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.524.tgz", - "integrity": "sha512-iTmhuiGXYo29QoFXwwXbxhAKiDRZQzme6wYVaZNoitg9h1iRaMGu3vNvDyk+gqu5ETK1D6ug9PC5GVS7kSURuw==" + "version": "1.4.530", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.530.tgz", + "integrity": "sha512-rsJ9O8SCI4etS8TBsXuRfHa2eZReJhnGf5MHZd3Vo05PukWHKXhk3VQGbHHnDLa8nZz9woPCpLCMQpLGgkGNRA==" }, "node_modules/encodeurl": { "version": "1.0.2", @@ -2514,15 +2514,15 @@ } }, "node_modules/eslint": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", - "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", + "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.49.0", + "@eslint/js": "8.50.0", "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -3159,9 +3159,9 @@ } }, "node_modules/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.22.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.22.0.tgz", + "integrity": "sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==", "peer": true, "dependencies": { "type-fest": "^0.20.2" @@ -4911,9 +4911,9 @@ } }, "node_modules/qunit": { - "version": "2.19.4", - "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.19.4.tgz", - "integrity": "sha512-aqUzzUeCqlleWYKlpgfdHHw9C6KxkB9H3wNfiBg5yHqQMzy0xw/pbCRHYFkjl8MsP/t8qkTQE+JTYL71azgiew==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.20.0.tgz", + "integrity": "sha512-N8Fp1J55waE+QG1KwX2LOyqulZUToRrrPBqDOfYfuAMkEglFL15uwvmH1P4Tq/omQ/mGbBI8PEB3PhIfvUb+jg==", "dependencies": { "commander": "7.2.0", "node-watch": "0.7.3", @@ -5125,9 +5125,9 @@ } }, "node_modules/rollup": { - "version": "3.29.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.2.tgz", - "integrity": "sha512-CJouHoZ27v6siztc21eEQGo0kIcE5D1gVPA571ez0mMYb25LGYGKnVNXpEj5MGlepmDWGXNjDB5q7uNiPHC11A==", + "version": "3.29.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.3.tgz", + "integrity": "sha512-T7du6Hum8jOkSWetjRgbwpM6Sy0nECYrYRSmZjayFcOddtKJWU4d17AC3HNUk7HRuqy4p+G7aEZclSHytqUmEg==", "bin": { "rollup": "dist/bin/rollup" }, @@ -5857,9 +5857,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "funding": [ { "type": "opencollective", @@ -6191,9 +6191,9 @@ } }, "@eslint-community/regexpp": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz", - "integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.2.tgz", + "integrity": "sha512-0MGxAVt1m/ZK+LTJp/j0qF7Hz97D9O/FH9Ms3ltnyIdDD57cbb1ACIQTkbHvNXtWDv5TPq7w5Kq56+cNukbo7g==", "peer": true }, "@eslint/eslintrc": { @@ -6214,9 +6214,9 @@ } }, "@eslint/js": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", - "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", + "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", "peer": true }, "@humanwhocodes/config-array": { @@ -6248,16 +6248,16 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "@microsoft/api-extractor": { - "version": "7.37.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.37.0.tgz", - "integrity": "sha512-df/wffWpDhYRw7kzdxeHGsCpim+dC8aFiZlsJb4uFvVPWhBZpDzOhQxSUTFx3Df1ORY+/JjuPR3fDE9Hq+PHzQ==", + "version": "7.37.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.37.1.tgz", + "integrity": "sha512-wbTL7TZG+9SPvYKwk26390ltoP/uR5621dniqhVp+5OHcn7wIKsT7vX9d/wvdAXD3Ft+7pAiCt6y3dBLFfY/0w==", "requires": { - "@microsoft/api-extractor-model": "7.28.0", + "@microsoft/api-extractor-model": "7.28.1", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.60.0", - "@rushstack/rig-package": "0.5.0", - "@rushstack/ts-command-line": "4.16.0", + "@rushstack/node-core-library": "3.60.1", + "@rushstack/rig-package": "0.5.1", + "@rushstack/ts-command-line": "4.16.1", "colors": "~1.2.1", "lodash": "~4.17.15", "resolve": "~1.22.1", @@ -6274,13 +6274,13 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.0.tgz", - "integrity": "sha512-QIMtUVm1tqiKG+M6ciFgRShcDoovyltaeg+CbyOnyr7SMrp6gg0ojK5/nToMqR9kAvsTS4QVgW4Twl50EoAjcw==", + "version": "7.28.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.1.tgz", + "integrity": "sha512-1hD9gQRu8VR53/e8GI+aql7MtWXHE/XtpOSgphJ6SB7AswqJT0mRZVufUbg3D57UdrchvLKz9b+zqay0Oq2vgg==", "requires": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.60.0" + "@rushstack/node-core-library": "3.60.1" } }, "@microsoft/applicationinsights-web-snippet": { @@ -7067,9 +7067,9 @@ } }, "@rushstack/node-core-library": { - "version": "3.60.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.60.0.tgz", - "integrity": "sha512-PcyrqhILvzU+65wMFybQ2VeGNnU5JzhDq2OvUi3j6jPUxyllM7b2hrRUwCuVaYboewYzIbpzXFzgxe2K7ii1nw==", + "version": "3.60.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.60.1.tgz", + "integrity": "sha512-cWKCImfezPvILKu5eUPkz0Mp/cO/zOSJdPD64KHliBcdmbPHg/sF4rEL7WJkWywXT1RQ/U/N8uKdXMe7jDCXNw==", "requires": { "colors": "~1.2.1", "fs-extra": "~7.0.1", @@ -7081,18 +7081,18 @@ } }, "@rushstack/rig-package": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.0.tgz", - "integrity": "sha512-bGnOW4DWHOePDiABKy6qyqYJl9i7fKn4bRucExRVt5QzyPxuVHMl8CMmCabtoNSpXzgG3qymWOrMoa/W2PpJrw==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.1.tgz", + "integrity": "sha512-pXRYSe29TjRw7rqxD4WS3HN/sRSbfr+tJs4a9uuaSIBAITbUggygdhuG0VrO0EO+QqH91GhYMN4S6KRtOEmGVA==", "requires": { "resolve": "~1.22.1", "strip-json-comments": "~3.1.1" } }, "@rushstack/ts-command-line": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.16.0.tgz", - "integrity": "sha512-WJKhdR9ThK9Iy7t78O3at7I3X4Ssp5RRZay/IQa8NywqkFy/DQbT3iLouodMMdUwLZD9n8n++xLubVd3dkmpkg==", + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.16.1.tgz", + "integrity": "sha512-+OCsD553GYVLEmz12yiFjMOzuPeCiZ3f8wTiFHL30ZVXexTyPmgjwXEhg2K2P0a2lVf+8YBy7WtPoflB2Fp8/A==", "requires": { "@types/argparse": "1.0.38", "argparse": "~1.0.9", @@ -7171,9 +7171,9 @@ } }, "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.2.tgz", + "integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==" }, "@types/file-saver": { "version": "2.0.5", @@ -7235,9 +7235,9 @@ } }, "@types/lodash": { - "version": "4.14.198", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz", - "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==" + "version": "4.14.199", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.199.tgz", + "integrity": "sha512-Vrjz5N5Ia4SEzWWgIVwnHNEnb1UE1XMkvY5DGXrAeOGE9imk0hgTHh5GyDjLDJi9OTCn9oo9dXH1uToK1VRfrg==" }, "@types/minimatch": { "version": "5.1.2", @@ -7255,9 +7255,9 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "@types/prop-types": { - "version": "15.7.6", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.6.tgz", - "integrity": "sha512-RK/kBbYOQQHLYj9Z95eh7S6t7gq4Ojt/NT8HTk8bWVhA5DaF+5SMnxHKkP4gPNN3wAZkKP+VjAf0ebtYzf+fxg==" + "version": "15.7.7", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.7.tgz", + "integrity": "sha512-FbtmBWCcSa2J4zL781Zf1p5YUBXQomPEcep9QZCfRfQgTxz3pJWiDFLebohZ9fFntX5ibzOkSsrJ0TEew8cAog==" }, "@types/qunit": { "version": "2.19.6", @@ -7265,9 +7265,9 @@ "integrity": "sha512-bz9STa6EHurtpSfn5cNiScBladlw43bM+7luQA985Kd9YlF4dZaLmKt3c5/oSyN1AWAl50YBpqTq0BxCP64nGg==" }, "@types/react": { - "version": "16.14.46", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.46.tgz", - "integrity": "sha512-Am4pyXMrr6cWWw/TN3oqHtEZl0j+G6Up/O8m65+xF/3ZaUgkv1GAtTPWw4yNRmH0HJXmur6xKCKoMo3rBGynuw==", + "version": "16.14.47", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.47.tgz", + "integrity": "sha512-m0EmmY73mbQegA+aqo0+O/hHU9iTi+hNYotJ3cM4sLFox8NqZv3XVXQhhqpd3YH6YC7h+YIyJFd36O5KlaJLCA==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -7296,14 +7296,14 @@ } }, "@types/scheduler": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", - "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" + "version": "0.16.4", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.4.tgz", + "integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==" }, "@types/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", "peer": true }, "@types/sinon": { @@ -7312,25 +7312,25 @@ "integrity": "sha512-Tt7w/ylBS/OEAlSCwzB0Db1KbxnkycP/1UkQpbvKFYoUuRn4uYsC3xh5TRPrOjTy0i8TIkSz1JdNL4GPVdf3KQ==" }, "@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.1.tgz", + "integrity": "sha512-CHzgNU3qYBnp/O4S3yv2tXPlvMTq0YWSTVg2/JYLqWZGHwwgJGAwd00poay/11asPq8wLFwHzubyInqHIFmmiw==", "optional": true, "requires": { "@types/node": "*" } }, "@typescript-eslint/eslint-plugin": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.2.tgz", - "integrity": "sha512-ooaHxlmSgZTM6CHYAFRlifqh1OAr3PAQEwi7lhYhaegbnXrnh7CDcHmc3+ihhbQC7H0i4JF0psI5ehzkF6Yl6Q==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz", + "integrity": "sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA==", "peer": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/type-utils": "6.7.2", - "@typescript-eslint/utils": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/type-utils": "6.7.3", + "@typescript-eslint/utils": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -7340,54 +7340,54 @@ } }, "@typescript-eslint/parser": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.2.tgz", - "integrity": "sha512-KA3E4ox0ws+SPyxQf9iSI25R6b4Ne78ORhNHeVKrPQnoYsb9UhieoiRoJgrzgEeKGOXhcY1i8YtOeCHHTDa6Fw==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", + "integrity": "sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==", "peer": true, "requires": { - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/typescript-estree": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz", - "integrity": "sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", + "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", "peer": true, "requires": { - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2" + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3" } }, "@typescript-eslint/type-utils": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.2.tgz", - "integrity": "sha512-36F4fOYIROYRl0qj95dYKx6kybddLtsbmPIYNK0OBeXv2j9L5nZ17j9jmfy+bIDHKQgn2EZX+cofsqi8NPATBQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.3.tgz", + "integrity": "sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw==", "peer": true, "requires": { - "@typescript-eslint/typescript-estree": "6.7.2", - "@typescript-eslint/utils": "6.7.2", + "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/utils": "6.7.3", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz", - "integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", + "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", "peer": true }, "@typescript-eslint/typescript-estree": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz", - "integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", + "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", "peer": true, "requires": { - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -7396,27 +7396,27 @@ } }, "@typescript-eslint/utils": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.2.tgz", - "integrity": "sha512-ZCcBJug/TS6fXRTsoTkgnsvyWSiXwMNiPzBUani7hDidBdj1779qwM1FIAmpH4lvlOZNF3EScsxxuGifjpLSWQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.3.tgz", + "integrity": "sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg==", "peer": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/typescript-estree": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.3", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz", - "integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", + "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", "peer": true, "requires": { - "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/types": "6.7.3", "eslint-visitor-keys": "^3.4.1" } }, @@ -7637,14 +7637,14 @@ } }, "browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "version": "4.21.11", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.11.tgz", + "integrity": "sha512-xn1UXOKUz7DjdGlg9RrUr0GGiWzI97UQJnugHtH0OLDfJB7jMgoIkYvRIEO1l9EeEERVqeqLYOcFBW9ldjypbQ==", "requires": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", + "caniuse-lite": "^1.0.30001538", + "electron-to-chromium": "^1.4.526", "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" + "update-browserslist-db": "^1.0.13" } }, "buffer": { @@ -7701,9 +7701,9 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "caniuse-lite": { - "version": "1.0.30001538", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001538.tgz", - "integrity": "sha512-HWJnhnID+0YMtGlzcp3T9drmBJUVDchPJ08tpUGFLs9CYlwWPH2uLgpHn8fND5pCgXVtnGS3H4QR9XLMHVNkHw==" + "version": "1.0.30001539", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001539.tgz", + "integrity": "sha512-hfS5tE8bnNiNvEOEkm8HElUHroYwlqMMENEzELymy77+tJ6m+gA2krtHl5hxJaj71OlpC2cHZbdSMX1/YEqEkA==" }, "chalk": { "version": "4.1.2", @@ -7983,9 +7983,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { - "version": "1.4.524", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.524.tgz", - "integrity": "sha512-iTmhuiGXYo29QoFXwwXbxhAKiDRZQzme6wYVaZNoitg9h1iRaMGu3vNvDyk+gqu5ETK1D6ug9PC5GVS7kSURuw==" + "version": "1.4.530", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.530.tgz", + "integrity": "sha512-rsJ9O8SCI4etS8TBsXuRfHa2eZReJhnGf5MHZd3Vo05PukWHKXhk3VQGbHHnDLa8nZz9woPCpLCMQpLGgkGNRA==" }, "encodeurl": { "version": "1.0.2", @@ -8025,15 +8025,15 @@ "peer": true }, "eslint": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", - "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", + "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", "peer": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.49.0", + "@eslint/js": "8.50.0", "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -8527,9 +8527,9 @@ } }, "globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.22.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.22.0.tgz", + "integrity": "sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==", "peer": true, "requires": { "type-fest": "^0.20.2" @@ -9829,9 +9829,9 @@ "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" }, "qunit": { - "version": "2.19.4", - "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.19.4.tgz", - "integrity": "sha512-aqUzzUeCqlleWYKlpgfdHHw9C6KxkB9H3wNfiBg5yHqQMzy0xw/pbCRHYFkjl8MsP/t8qkTQE+JTYL71azgiew==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.20.0.tgz", + "integrity": "sha512-N8Fp1J55waE+QG1KwX2LOyqulZUToRrrPBqDOfYfuAMkEglFL15uwvmH1P4Tq/omQ/mGbBI8PEB3PhIfvUb+jg==", "requires": { "commander": "7.2.0", "node-watch": "0.7.3", @@ -9994,9 +9994,9 @@ } }, "rollup": { - "version": "3.29.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.2.tgz", - "integrity": "sha512-CJouHoZ27v6siztc21eEQGo0kIcE5D1gVPA571ez0mMYb25LGYGKnVNXpEj5MGlepmDWGXNjDB5q7uNiPHC11A==", + "version": "3.29.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.3.tgz", + "integrity": "sha512-T7du6Hum8jOkSWetjRgbwpM6Sy0nECYrYRSmZjayFcOddtKJWU4d17AC3HNUk7HRuqy4p+G7aEZclSHytqUmEg==", "requires": { "fsevents": "~2.3.2" } @@ -10543,9 +10543,9 @@ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" diff --git a/shared/1ds-core-js/src/Index.ts b/shared/1ds-core-js/src/Index.ts index 4d415bcd7..be973c9b9 100644 --- a/shared/1ds-core-js/src/Index.ts +++ b/shared/1ds-core-js/src/Index.ts @@ -66,7 +66,8 @@ export { // Dynamic Config definitions IConfigCheckFn, IConfigDefaultCheck, IConfigDefaults, IConfigSetFn, IDynamicConfigHandler, IDynamicPropertyHandler, IWatchDetails, IWatcherHandler, WatcherFunction, - createDynamicConfig, onConfigChange, getDynamicConfigHandler, blockDynamicConversion, forceDynamicConversion + createDynamicConfig, onConfigChange, getDynamicConfigHandler, blockDynamicConversion, forceDynamicConversion, + IPayloadData, IXHROverride, OnCompleteCallback, SendPOSTFunction } from "@microsoft/applicationinsights-core-js"; export { diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Enums/SendRequestReason.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Enums/SendRequestReason.ts index d8885dde6..4f317ccf6 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK.Enums/SendRequestReason.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Enums/SendRequestReason.ts @@ -7,7 +7,7 @@ export const enum SendRequestReason { /** * No specific reason was specified */ - Undefined = 0, + Undefined = 0, /** * Events are being sent based on the normal event schedule / timer. @@ -54,3 +54,22 @@ export const enum SendRequestReason { */ MaxQueuedEvents = 20 } + +export const enum TransportType { + /** + * Use the default available api + */ + NotSet = 0, + /** + * Use XMLHttpRequest or XMLDomainRequest if available + */ + Xhr = 1, + /** + * Use the Fetch api if available + */ + Fetch = 2, + /** + * Use sendBeacon api if available + */ + Beacon = 3 +} diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IXHROverride.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IXHROverride.ts new file mode 100644 index 000000000..821e0202c --- /dev/null +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IXHROverride.ts @@ -0,0 +1,36 @@ +import { IPromise } from "@nevware21/ts-async"; +import { SendRequestReason } from "../applicationinsights-core-js"; + +/** IPayloadData describes interface of payload sent via POST channel */ +export interface IPayloadData { + urlString: string; + data: Uint8Array | string; + headers?: { [name: string]: string }; + timeout?: number; + disableXhrSync?: boolean; + disableFetchKeepAlive?: boolean; + sendReason?: SendRequestReason; +} + +/** +* SendPOSTFunction type defines how an HTTP POST request is sent to an ingestion server +* @param payload - The payload object that should be sent, contains the url, bytes/string and headers for the request +* @param oncomplete - The function to call once the request has completed whether a success, failure or timeout +* @param sync - A boolean flag indicating whether the request should be sent as a synchronous request. +*/ +export type SendPOSTFunction = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => void | IPromise; + +export type OnCompleteCallback = (status: number, headers: { [headerName: string]: string; }, response?: string) => void; + + + +/** +* The IXHROverride interface overrides the way HTTP requests are sent. +*/ +export interface IXHROverride { + sendPOST: SendPOSTFunction; +} + + + + diff --git a/shared/AppInsightsCore/src/applicationinsights-core-js.ts b/shared/AppInsightsCore/src/applicationinsights-core-js.ts index 007c8dbfc..781ebac73 100644 --- a/shared/AppInsightsCore/src/applicationinsights-core-js.ts +++ b/shared/AppInsightsCore/src/applicationinsights-core-js.ts @@ -12,9 +12,10 @@ export { ITelemetryPluginChain } from "./JavaScriptSDK.Interfaces/ITelemetryPlug export { IDiagnosticLogger } from "./JavaScriptSDK.Interfaces/IDiagnosticLogger"; export { InstrumentorHooksCallback, IInstrumentHooksCallbacks, IInstrumentHooks, IInstrumentHook, IInstrumentCallDetails } from "./JavaScriptSDK.Interfaces/IInstrumentHooks"; export { IUnloadableComponent } from "./JavaScriptSDK.Interfaces/IUnloadableComponent"; +export { IPayloadData, SendPOSTFunction, IXHROverride, OnCompleteCallback } from "./JavaScriptSDK.Interfaces/IXHROverride" export { IUnloadHook, ILegacyUnloadHook } from "./JavaScriptSDK.Interfaces/IUnloadHook"; export { eEventsDiscardedReason, EventsDiscardedReason } from "./JavaScriptSDK.Enums/EventsDiscardedReason"; -export { SendRequestReason } from "./JavaScriptSDK.Enums/SendRequestReason"; +export { SendRequestReason, TransportType } from "./JavaScriptSDK.Enums/SendRequestReason"; export { TelemetryUpdateReason } from "./JavaScriptSDK.Enums/TelemetryUpdateReason"; export { TelemetryUnloadReason } from "./JavaScriptSDK.Enums/TelemetryUnloadReason"; export { throwAggregationError } from "./JavaScriptSDK/AggregationError";