@microsoft/1ds-post-js 3.1.9 → 3.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +1 -0
  2. package/bundle/{ms.post-3.1.9.gbl.js → ms.post-3.1.10.gbl.js} +196 -92
  3. package/bundle/ms.post-3.1.10.gbl.js.map +1 -0
  4. package/bundle/ms.post-3.1.10.gbl.min.js +7 -0
  5. package/bundle/ms.post-3.1.10.gbl.min.js.map +1 -0
  6. package/bundle/ms.post-3.1.10.integrity.json +46 -0
  7. package/bundle/{ms.post-3.1.9.js → ms.post-3.1.10.js} +196 -92
  8. package/bundle/ms.post-3.1.10.js.map +1 -0
  9. package/bundle/ms.post-3.1.10.min.js +7 -0
  10. package/bundle/ms.post-3.1.10.min.js.map +1 -0
  11. package/bundle/ms.post.gbl.js +195 -91
  12. package/bundle/ms.post.gbl.js.map +1 -1
  13. package/bundle/ms.post.gbl.min.js +2 -2
  14. package/bundle/ms.post.gbl.min.js.map +1 -1
  15. package/bundle/ms.post.integrity.json +17 -17
  16. package/bundle/ms.post.js +195 -91
  17. package/bundle/ms.post.js.map +1 -1
  18. package/bundle/ms.post.min.js +2 -2
  19. package/bundle/ms.post.min.js.map +1 -1
  20. package/dist/ms.post.js +140 -72
  21. package/dist/ms.post.js.map +1 -1
  22. package/dist/ms.post.min.js +2 -2
  23. package/dist/ms.post.min.js.map +1 -1
  24. package/dist-esm/src/BatchNotificationActions.js +1 -1
  25. package/dist-esm/src/ClockSkewManager.js +1 -1
  26. package/dist-esm/src/Constants.d.ts +24 -0
  27. package/dist-esm/src/Constants.js +30 -0
  28. package/dist-esm/src/Constants.js.map +1 -0
  29. package/dist-esm/src/DataModels.d.ts +6 -0
  30. package/dist-esm/src/DataModels.js +1 -1
  31. package/dist-esm/src/EventBatch.d.ts +5 -2
  32. package/dist-esm/src/EventBatch.js +35 -15
  33. package/dist-esm/src/EventBatch.js.map +1 -1
  34. package/dist-esm/src/HttpManager.d.ts +1 -1
  35. package/dist-esm/src/HttpManager.js +112 -64
  36. package/dist-esm/src/HttpManager.js.map +1 -1
  37. package/dist-esm/src/Index.js +1 -1
  38. package/dist-esm/src/KillSwitch.js +1 -1
  39. package/dist-esm/src/PostChannel.js +6 -5
  40. package/dist-esm/src/PostChannel.js.map +1 -1
  41. package/dist-esm/src/RetryPolicy.js +1 -1
  42. package/dist-esm/src/Serializer.js +1 -1
  43. package/dist-esm/src/typings/XDomainRequest.js +1 -1
  44. package/package.json +3 -3
  45. package/src/Constants.ts +27 -0
  46. package/src/DataModels.ts +8 -1
  47. package/src/EventBatch.ts +47 -14
  48. package/src/HttpManager.ts +143 -66
  49. package/src/PostChannel.ts +4 -3
  50. package/bundle/ms.post-3.1.9.gbl.js.map +0 -1
  51. package/bundle/ms.post-3.1.9.gbl.min.js +0 -7
  52. package/bundle/ms.post-3.1.9.gbl.min.js.map +0 -1
  53. package/bundle/ms.post-3.1.9.integrity.json +0 -46
  54. package/bundle/ms.post-3.1.9.js.map +0 -1
  55. package/bundle/ms.post-3.1.9.min.js +0 -7
  56. package/bundle/ms.post-3.1.9.min.js.map +0 -1
@@ -24,6 +24,12 @@ import EVTClockSkewManager from "./ClockSkewManager";
24
24
  import dynamicProto from "@microsoft/dynamicproto-js";
25
25
  import { IChannelConfiguration } from "./Index";
26
26
  import { XDomainRequest as IXDomainRequest } from "./typings/XDomainRequest";
27
+ import {
28
+ defaultCacheControl, defaultContentType, DisabledPropertyName, Method, strApiKey, strAuthXToken, strCacheControl,
29
+ strClientId, strClientVersion, strContentTypeHeader, strDropped, strKillDurationHeader, strKillDurationSecondsHeader,
30
+ strKillTokensHeader, strMsaDeviceTicket, strMsfpc, strOther, strRequeue, strResponseFail, strSending, strTimeDeltaHeader,
31
+ strTimeDeltaToApply, strUploadTime
32
+ } from "./Constants";
27
33
 
28
34
  // TypeScript removed this interface so we need to declare the global so we can check for it's existence.
29
35
  declare var XDomainRequest: {
@@ -31,23 +37,11 @@ declare var XDomainRequest: {
31
37
  new(): IXDomainRequest;
32
38
  };
33
39
 
34
- const Method = "POST";
35
- const DisabledPropertyName: string = "Microsoft_ApplicationInsights_BypassAjaxInstrumentation";
36
-
37
- const strDropped = "drop";
38
- const strSending = "send";
39
- const strRequeue = "requeue";
40
- const strResponseFail = "rspFail";
41
- const strOther = "oth";
42
-
43
- const defaultCacheControl = "no-cache, no-store";
44
- const defaultContentType = "application/x-json-stream";
45
- const strCacheControl = "cache-control";
46
- const strContentTypeHeader = "content-type";
47
- const strKillTokensHeader = "kill-tokens";
48
- const strKillDurationHeader = "kill-duration";
49
- const strKillDurationSecondsHeader = "kill-duration-seconds";
50
- const strTimeDeltaHeader = "time-delta-millis";
40
+ interface IRequestUrlDetails {
41
+ url: string,
42
+ hdrs: { [key: string]: string },
43
+ useHdrs: boolean
44
+ }
51
45
 
52
46
  /**
53
47
  * Identifies the default notification reason to the action names
@@ -60,6 +54,27 @@ const _eventActionMap: any = {
60
54
  [EventBatchNotificationReason.SizeLimitExceeded]: strDropped
61
55
  };
62
56
 
57
+ const _collectorQsHeaders = { };
58
+ const _collectorHeaderToQs = { };
59
+
60
+ function _addCollectorHeaderQsMapping(qsName: string, headerName: string) {
61
+ _collectorQsHeaders[qsName] = headerName;
62
+ _collectorHeaderToQs[headerName] = qsName;
63
+ }
64
+
65
+ _addCollectorHeaderQsMapping(strMsaDeviceTicket, strMsaDeviceTicket);
66
+
67
+ // ----------------------------------------------------------------------------------------------------------------
68
+ // Task 12886642: Need to wait until an updated version of the collector is released to return these as allowed in the OPTIONS call
69
+ // ----------------------------------------------------------------------------------------------------------------
70
+ //_addCollectorHeaderQsMapping(strClientVersion, strClientVersion);
71
+ //_addCollectorHeaderQsMapping(strClientId, "Client-Id");
72
+ //_addCollectorHeaderQsMapping(strApiKey, strApiKey);
73
+ //_addCollectorHeaderQsMapping(strTimeDeltaToApply, strTimeDeltaToApply);
74
+ //_addCollectorHeaderQsMapping(strUploadTime, strUploadTime);
75
+ //_addCollectorHeaderQsMapping(strAuthXToken, strAuthXToken);
76
+ // ----------------------------------------------------------------------------------------------------------------
77
+
63
78
  type OnCompleteCallback = (status: number, headers: { [headerName: string]: string }, response?: string) => void;
64
79
 
65
80
  function _getResponseText(xhr: XMLHttpRequest | IXDomainRequest) {
@@ -102,10 +117,21 @@ function _hasHeader(headers: any, header: string) {
102
117
  return hasHeader;
103
118
  }
104
119
 
120
+ function _addRequestDetails(details: IRequestUrlDetails, name: string, value: string, useHeaders: boolean) {
121
+ if (name && value && value.length > 0) {
122
+ if (useHeaders && _collectorQsHeaders[name]) {
123
+ details.hdrs[_collectorQsHeaders[name]] = value;
124
+ details.useHdrs = true;
125
+ } else {
126
+ details.url += "&" + name + "=" + value;
127
+ }
128
+ }
129
+ }
130
+
105
131
  /**
106
132
  * Class managing the sending of requests.
107
133
  */
108
- export default class HttpManager {
134
+ export class HttpManager {
109
135
  public sendHook: PayloadPreprocessorFunction | undefined;
110
136
  public sendListener: PayloadListenerFunction | undefined;
111
137
  public _responseHandlers: Array<(responseText: string) => void> = [];
@@ -115,8 +141,7 @@ export default class HttpManager {
115
141
  * @param requestQueue - The queue that contains the requests to be sent.
116
142
  */
117
143
  constructor(maxEventsPerBatch: number, maxConnections: number, maxRetries: number, actions: BatchNotificationActions) {
118
- let _urlString: string = "?cors=true&" + strContentTypeHeader.toLowerCase() + "=" + defaultContentType + "&client-id=NO_AUTH&client-version="
119
- + FullVersionString;
144
+ let _urlString: string = "?cors=true&" + strContentTypeHeader.toLowerCase() + "=" + defaultContentType;
120
145
  let _killSwitch: EVTKillSwitch = new EVTKillSwitch();
121
146
  let _paused = false;
122
147
  let _clockSkewManager = new EVTClockSkewManager();
@@ -133,6 +158,7 @@ export default class HttpManager {
133
158
  let _enableEventTimings = false;
134
159
  let _cookieMgr: ICookieMgr;
135
160
  let _isUnloading = false;
161
+ let _useHeaders = false;
136
162
 
137
163
  dynamicProto(HttpManager, this, (_self) => {
138
164
  let _sendCredentials = true;
@@ -149,6 +175,9 @@ export default class HttpManager {
149
175
  }
150
176
 
151
177
  _urlString = endpointUrl + _urlString;
178
+
179
+ // Task 12886642: Defaulting to 'false' until the Collector handles sending upload-time header in the OPTIONS call
180
+ _useHeaders = !isUndefined(channelConfig.avoidOptions) ? !channelConfig.avoidOptions : false;
152
181
  _core = core;
153
182
  _cookieMgr = core.getCookieMgr();
154
183
  _enableEventTimings = !(_core.config as IExtendedConfiguration).disableEventTimings;
@@ -160,13 +189,6 @@ export default class HttpManager {
160
189
  enableCompoundKey = !!channelConfig.enableCompoundKey;
161
190
  }
162
191
 
163
- // For this to work the collection MUST return "Cache-control" in the OPTIONS response in the Allow-Control-Allow-Headers
164
- // ONLY un-comment the below once the collector has changed and deployed.
165
- // if (!!channelConfig.disableCacheHeader) {
166
- // // Stop Chrome from stalling/throttling requests see task #7178858
167
- // _self.addHeader("Cache-control", "no-cache, no-store");
168
- // }
169
-
170
192
  _useBeacons = !isReactNative(); // Only use beacons if not running in React Native
171
193
  _serializer = new Serializer(_core, valueSanitizer, stringifyObjects, enableCompoundKey);
172
194
 
@@ -288,6 +310,8 @@ export default class HttpManager {
288
310
  }
289
311
 
290
312
  function _fetchSendPost(payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) {
313
+ let ignoreResponse = false;
314
+ let responseHandled = false;
291
315
  let requestInit: RequestInit = {
292
316
  body: payload.data,
293
317
  method: Method,
@@ -296,6 +320,11 @@ export default class HttpManager {
296
320
 
297
321
  if (sync) {
298
322
  requestInit.keepalive = true;
323
+ if ((payload as IInternalPayloadData)._sendReason === SendRequestReason.Unload) {
324
+ // As a sync request (during unload), it is unlikely that we will get a chance to process the response so
325
+ // just like beacon send assume that the events have been accepted and processed
326
+ ignoreResponse = true;
327
+ }
299
328
  }
300
329
 
301
330
  if (_sendCredentials) {
@@ -321,13 +350,26 @@ export default class HttpManager {
321
350
  responseText = text;
322
351
  });
323
352
  }
324
- _doOnComplete(oncomplete, response.status, headerMap, responseText);
325
- _handleCollectorResponse(responseText);
353
+
354
+ if (!responseHandled) {
355
+ responseHandled = true;
356
+ _doOnComplete(oncomplete, response.status, headerMap, responseText);
357
+ _handleCollectorResponse(responseText);
358
+ }
326
359
  }).catch((error) => {
327
360
  // In case there is an error in the request. Set the status to 0
328
361
  // so that the events can be retried later.
329
- _doOnComplete(oncomplete, 0, {});
362
+ if (!responseHandled) {
363
+ responseHandled = true;
364
+ _doOnComplete(oncomplete, 0, {});
365
+ }
330
366
  });
367
+
368
+ if (ignoreResponse && !responseHandled) {
369
+ // Assume success during unload processing
370
+ responseHandled = true;
371
+ _doOnComplete(oncomplete, 200, {});
372
+ }
331
373
  }
332
374
 
333
375
  function _xhrSendPost(payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) {
@@ -670,8 +712,36 @@ export default class HttpManager {
670
712
  }
671
713
  }
672
714
 
673
- function _buildQueryString(thePayload: ISerializedPayload) {
674
- let urlString = _urlString;
715
+ function _buildRequestDetails(thePayload: ISerializedPayload, useHeaders: boolean): IRequestUrlDetails {
716
+ let requestDetails: IRequestUrlDetails = {
717
+ url: _urlString,
718
+ hdrs: {},
719
+ useHdrs: false // Assume no headers
720
+ };
721
+
722
+ // ----------------------------------------------------------------------------------------------------------------
723
+ // Task 12886642: Need to wait until an updated version of the collector is released to return these as allowed in the OPTIONS call
724
+ // ----------------------------------------------------------------------------------------------------------------
725
+ // if (!useHeaders) {
726
+ // // Attempt to map headers to a query string if possible
727
+ // objForEachKey(_headers, (name, value) => {
728
+ // if (_collectorHeaderToQs[name]) {
729
+ // _addRequestDetails(requestDetails, _collectorHeaderToQs[name], value, false);
730
+ // } else {
731
+ // // No mapping, so just include in the headers anyway (may not get sent if using sendBeacon())
732
+ // requestDetails.hdrs[name] = value;
733
+ // requestDetails.useHdrs = true;
734
+ // }
735
+ // });
736
+ // } else {
737
+ // Copy the pre-defined headers into the payload headers
738
+ requestDetails.hdrs = extend(requestDetails.hdrs, _headers);
739
+ requestDetails.useHdrs = (objKeys(requestDetails.hdrs).length > 0);
740
+ // }
741
+ // ----------------------------------------------------------------------------------------------------------------
742
+
743
+ _addRequestDetails(requestDetails, strClientId, "NO_AUTH", useHeaders);
744
+ _addRequestDetails(requestDetails, strClientVersion, FullVersionString, useHeaders);
675
745
 
676
746
  let apiQsKeys = "";
677
747
  arrForEach(thePayload.apiKeys, (apiKey) => {
@@ -682,33 +752,30 @@ export default class HttpManager {
682
752
  apiQsKeys += apiKey;
683
753
  });
684
754
 
685
- if (apiQsKeys.length > 0) {
686
- urlString += "&apikey=" + apiQsKeys;
687
- }
688
-
689
- urlString += "&upload-time=" + dateNow().toString();
755
+ _addRequestDetails(requestDetails, strApiKey, apiQsKeys, useHeaders);
756
+ _addRequestDetails(requestDetails, strUploadTime, dateNow().toString(), useHeaders);
690
757
 
691
758
  let msfpc = _getMsfpc(thePayload);
692
759
  if (isValueAssigned(msfpc)) {
693
- urlString = urlString + "&ext.intweb.msfpc=" + msfpc;
760
+ requestDetails.url += "&ext.intweb.msfpc=" + msfpc;
694
761
  }
695
762
 
696
763
  if (_clockSkewManager.shouldAddClockSkewHeaders()) {
697
- urlString += "&time-delta-to-apply-millis=" + _clockSkewManager.getClockSkewHeaderValue();
764
+ _addRequestDetails(requestDetails, strTimeDeltaToApply, _clockSkewManager.getClockSkewHeaderValue(), useHeaders);
698
765
  }
699
766
 
700
767
  if (_core.getWParam) {
701
768
  let wParam = _core.getWParam();
702
769
  if (wParam >= 0) {
703
- urlString += "&w=" + wParam;
770
+ requestDetails.url += "&w=" + wParam;
704
771
  }
705
772
  }
706
773
 
707
774
  for (let i = 0; i < _queryStringParameters.length; i++) {
708
- urlString += "&" + _queryStringParameters[i].name + "=" + _queryStringParameters[i].value;
775
+ requestDetails.url += "&" + _queryStringParameters[i].name + "=" + _queryStringParameters[i].value;
709
776
  }
710
777
 
711
- return urlString;
778
+ return requestDetails;
712
779
  }
713
780
 
714
781
  function _canUseSendBeaconApi() {
@@ -723,7 +790,24 @@ export default class HttpManager {
723
790
  function _doPayloadSend(thePayload: ISerializedPayload, serializationStart: number, serializationCompleted: number, sendReason: SendRequestReason) {
724
791
 
725
792
  if (thePayload && thePayload.payloadBlob && thePayload.payloadBlob.length > 0) {
726
- let urlString = _buildQueryString(thePayload);
793
+ let useSendHook = !!_self.sendHook;
794
+ let sendInterface = _sendInterfaces[thePayload.sendType];
795
+
796
+ // Send all data using a beacon style transport if closing mode is on or channel was teared down
797
+ if (!_isBeaconPayload(thePayload.sendType) && thePayload.isBeacon && thePayload.sendReason === SendRequestReason.Unload) {
798
+ sendInterface = _sendInterfaces[EventSendType.SendBeacon] || _sendInterfaces[EventSendType.SyncFetch] || sendInterface;
799
+ }
800
+
801
+ let useHeaders = _useHeaders;
802
+
803
+ // Disable header usage if we know we are using sendBeacon as additional headers are not supported
804
+ if (thePayload.isBeacon || sendInterface._transport === TransportType.Beacon) {
805
+ useHeaders = false;
806
+ }
807
+
808
+ let requestDetails = _buildRequestDetails(thePayload, useHeaders);
809
+ useHeaders = useHeaders || requestDetails.useHdrs;
810
+
727
811
  let sendEventStart = getTime();
728
812
  let strSendAttempt = "sendAttempt";
729
813
 
@@ -757,28 +841,24 @@ export default class HttpManager {
757
841
  // eslint-disable-next-line prefer-const
758
842
  let orgPayloadData: IInternalPayloadData = {
759
843
  data: thePayload.payloadBlob,
760
- urlString: urlString,
761
- headers: extend({}, _headers),
844
+ urlString: requestDetails.url,
845
+ headers: requestDetails.hdrs,
762
846
  _thePayload: thePayload,
763
847
  _sendReason: sendReason
764
848
  };
765
849
 
766
- if (!_hasHeader(orgPayloadData.headers, strCacheControl)) {
767
- orgPayloadData.headers[strCacheControl] = defaultCacheControl;
768
- }
769
-
770
- if (!_hasHeader(orgPayloadData.headers, strContentTypeHeader)) {
771
- orgPayloadData.headers[strContentTypeHeader] = defaultContentType;
850
+ // Only automatically add the following headers if already sending headers and we are not attempting to avoid an options call
851
+ if (useHeaders) {
852
+ if (!_hasHeader(orgPayloadData.headers, strCacheControl)) {
853
+ orgPayloadData.headers[strCacheControl] = defaultCacheControl;
854
+ }
855
+
856
+ if (!_hasHeader(orgPayloadData.headers, strContentTypeHeader)) {
857
+ orgPayloadData.headers[strContentTypeHeader] = defaultContentType;
858
+ }
772
859
  }
773
860
 
774
861
  let sender: (payload: IPayloadData) => void = null;
775
- let useSendHook = !!_self.sendHook;
776
-
777
- let sendInterface = _sendInterfaces[thePayload.sendType];
778
- // Send all data using a beacon style transport if closing mode is on or channel was teared down
779
- if (!_isBeaconPayload(thePayload.sendType) && thePayload.isBeacon && thePayload.sendReason === SendRequestReason.Unload) {
780
- sendInterface = _sendInterfaces[EventSendType.SendBeacon] || _sendInterfaces[EventSendType.SyncFetch] || sendInterface;
781
- }
782
862
 
783
863
  if (sendInterface) {
784
864
  // Send sync requests if the request is immediate or we are tearing down telemetry.
@@ -1048,12 +1128,9 @@ export default class HttpManager {
1048
1128
 
1049
1129
  function _getMsfpc(thePayload: ISerializedPayload): string {
1050
1130
  for (let lp = 0; lp < thePayload.batches.length; lp++) {
1051
- let batchEvents = thePayload.batches[lp].events();
1052
- for (let evtLp = 0; evtLp < batchEvents.length; evtLp++) {
1053
- let intWeb = ((batchEvents[evtLp].ext || {})["intweb"] || {});
1054
- if (isValueAssigned(intWeb["msfpc"])) {
1055
- return encodeURIComponent(intWeb["msfpc"]);
1056
- }
1131
+ let msfpc = thePayload.batches[lp].Msfpc();
1132
+ if (msfpc) {
1133
+ return encodeURIComponent(msfpc);
1057
1134
  }
1058
1135
  }
1059
1136
 
@@ -1074,9 +1151,9 @@ export default class HttpManager {
1074
1151
  }
1075
1152
  if (responseText) {
1076
1153
  let response = JSON.parse(responseText) as ICollectorResult;
1077
- if (isValueAssigned(response.webResult) && isValueAssigned(response.webResult.msfpc)) {
1154
+ if (isValueAssigned(response.webResult) && isValueAssigned(response.webResult[strMsfpc])) {
1078
1155
  // Set cookie
1079
- _cookieMgr.set("MSFPC", response.webResult.msfpc, 365 * 86400);
1156
+ _cookieMgr.set("MSFPC", response.webResult[strMsfpc], 365 * 86400);
1080
1157
  }
1081
1158
  }
1082
1159
  } catch (ex) {
@@ -16,9 +16,10 @@ import {
16
16
  EventBatchNotificationReason,
17
17
  } from "./DataModels";
18
18
  import { EventBatch } from "./EventBatch";
19
- import HttpManager from "./HttpManager";
19
+ import { HttpManager } from "./HttpManager";
20
20
  import RetryPolicy from "./RetryPolicy";
21
21
  import dynamicProto from "@microsoft/dynamicproto-js";
22
+ import { strMsaDeviceTicket } from "./Constants";
22
23
 
23
24
  const FlushCheckTimer = 0.250; // This needs to be in seconds, so this is 250ms
24
25
  const MaxNumberEventPerBatch = 500;
@@ -420,7 +421,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
420
421
  };
421
422
 
422
423
  _self.setMsaAuthTicket = (ticket: string) => {
423
- _httpManager.addHeader("AuthMsaDeviceTicket", ticket);
424
+ _httpManager.addHeader(strMsaDeviceTicket, ticket);
424
425
  };
425
426
 
426
427
  _self.hasEvents = _hasEvents;
@@ -613,7 +614,7 @@ export default class PostChannel extends BaseTelemetryPlugin implements IChannel
613
614
 
614
615
  const latency = event.latency;
615
616
  let eventBatch = _getEventBatch(event.iKey, latency, true);
616
- if (eventBatch.addEvents([event], append)) {
617
+ if (eventBatch.addEvent(event)) {
617
618
  if (latency !== EventLatency.Immediate) {
618
619
  _queueSize++;
619
620