@edx/frontend-platform 3.5.0 → 3.6.1

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 (86) hide show
  1. package/analytics/MockAnalyticsService.js +6 -19
  2. package/analytics/MockAnalyticsService.js.map +1 -1
  3. package/analytics/SegmentAnalyticsService.js +53 -57
  4. package/analytics/SegmentAnalyticsService.js.map +1 -1
  5. package/analytics/index.js.map +1 -1
  6. package/analytics/interface.js +9 -9
  7. package/analytics/interface.js.map +1 -1
  8. package/auth/AxiosCsrfTokenService.js +36 -58
  9. package/auth/AxiosCsrfTokenService.js.map +1 -1
  10. package/auth/AxiosJwtAuthService.js +105 -150
  11. package/auth/AxiosJwtAuthService.js.map +1 -1
  12. package/auth/AxiosJwtTokenService.js +101 -148
  13. package/auth/AxiosJwtTokenService.js.map +1 -1
  14. package/auth/LocalForageCache.js +89 -108
  15. package/auth/LocalForageCache.js.map +1 -1
  16. package/auth/MockAuthService.js +10 -35
  17. package/auth/MockAuthService.js.map +1 -1
  18. package/auth/index.js.map +1 -1
  19. package/auth/interceptors/createCsrfTokenProviderInterceptor.js +35 -50
  20. package/auth/interceptors/createCsrfTokenProviderInterceptor.js.map +1 -1
  21. package/auth/interceptors/createJwtTokenProviderInterceptor.js +33 -47
  22. package/auth/interceptors/createJwtTokenProviderInterceptor.js.map +1 -1
  23. package/auth/interceptors/createProcessAxiosRequestErrorInterceptor.js +15 -27
  24. package/auth/interceptors/createProcessAxiosRequestErrorInterceptor.js.map +1 -1
  25. package/auth/interceptors/createRetryInterceptor.js +75 -105
  26. package/auth/interceptors/createRetryInterceptor.js.map +1 -1
  27. package/auth/interface.js +41 -58
  28. package/auth/interface.js.map +1 -1
  29. package/auth/utils.js +22 -40
  30. package/auth/utils.js.map +1 -1
  31. package/config.js +6 -7
  32. package/config.js.map +1 -1
  33. package/constants.js +8 -8
  34. package/constants.js.map +1 -1
  35. package/i18n/countries.js +9 -15
  36. package/i18n/countries.js.map +1 -1
  37. package/i18n/index.js +1 -0
  38. package/i18n/index.js.map +1 -1
  39. package/i18n/injectIntlWithShim.js +4 -28
  40. package/i18n/injectIntlWithShim.js.map +1 -1
  41. package/i18n/languages.js +11 -17
  42. package/i18n/languages.js.map +1 -1
  43. package/i18n/lib.js +64 -56
  44. package/i18n/lib.js.map +1 -1
  45. package/i18n/scripts/transifex-utils.js +5 -20
  46. package/i18n/scripts/transifex-utils.js.map +1 -1
  47. package/index.js.map +1 -1
  48. package/initialize.js +176 -228
  49. package/initialize.js.map +1 -1
  50. package/logging/MockLoggingService.js +5 -9
  51. package/logging/MockLoggingService.js.map +1 -1
  52. package/logging/NewRelicLoggingService.js +9 -33
  53. package/logging/NewRelicLoggingService.js.map +1 -1
  54. package/logging/index.js.map +1 -1
  55. package/logging/interface.js +7 -6
  56. package/logging/interface.js.map +1 -1
  57. package/package.json +4 -4
  58. package/pubSub.js +4 -3
  59. package/pubSub.js.map +1 -1
  60. package/react/AppContext.js +1 -1
  61. package/react/AppContext.js.map +1 -1
  62. package/react/AppProvider.js +13 -23
  63. package/react/AppProvider.js.map +1 -1
  64. package/react/AuthenticatedPageRoute.js +5 -13
  65. package/react/AuthenticatedPageRoute.js.map +1 -1
  66. package/react/ErrorBoundary.js +4 -21
  67. package/react/ErrorBoundary.js.map +1 -1
  68. package/react/ErrorPage.js +7 -17
  69. package/react/ErrorPage.js.map +1 -1
  70. package/react/LoginRedirect.js +1 -1
  71. package/react/LoginRedirect.js.map +1 -1
  72. package/react/OptionalReduxProvider.js +2 -4
  73. package/react/OptionalReduxProvider.js.map +1 -1
  74. package/react/PageRoute.js +3 -3
  75. package/react/PageRoute.js.map +1 -1
  76. package/react/hooks.js +2 -6
  77. package/react/hooks.js.map +1 -1
  78. package/react/index.js +1 -0
  79. package/react/index.js.map +1 -1
  80. package/testing/index.js +1 -0
  81. package/testing/index.js.map +1 -1
  82. package/testing/initializeMockApp.js +11 -11
  83. package/testing/initializeMockApp.js.map +1 -1
  84. package/testing/mockMessages.js.map +1 -1
  85. package/utils.js +15 -24
  86. package/utils.js.map +1 -1
@@ -1,11 +1,10 @@
1
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
2
-
1
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
2
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
3
3
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
4
-
5
4
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6
-
7
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
8
-
5
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
7
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
9
8
  /**
10
9
  * The MockAnalyticsService implements all functions of AnalyticsService as Jest mocks (jest.fn())).
11
10
  * It emulates the behavior of a real analytics service but witohut making any requests. It has no
@@ -16,48 +15,36 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
16
15
  */
17
16
  var MockAnalyticsService = /*#__PURE__*/_createClass(function MockAnalyticsService(_ref) {
18
17
  var _this = this;
19
-
20
18
  var httpClient = _ref.httpClient,
21
- loggingService = _ref.loggingService;
22
-
19
+ loggingService = _ref.loggingService;
23
20
  _classCallCheck(this, MockAnalyticsService);
24
-
25
21
  _defineProperty(this, "checkIdentifyCalled", jest.fn(function () {
26
22
  if (!_this.hasIdentifyBeenCalled) {
27
23
  _this.loggingService.logError('Identify must be called before other tracking events.');
28
24
  }
29
25
  }));
30
-
31
26
  _defineProperty(this, "sendTrackingLogEvent", jest.fn(function () {
32
27
  return Promise.resolve();
33
28
  }));
34
-
35
29
  _defineProperty(this, "identifyAuthenticatedUser", jest.fn(function (userId) {
36
30
  if (!userId) {
37
31
  throw new Error('UserId is required for identifyAuthenticatedUser.');
38
32
  }
39
-
40
33
  _this.hasIdentifyBeenCalled = true;
41
34
  }));
42
-
43
35
  _defineProperty(this, "identifyAnonymousUser", jest.fn(function () {
44
36
  _this.hasIdentifyBeenCalled = true;
45
37
  return Promise.resolve();
46
38
  }));
47
-
48
39
  _defineProperty(this, "sendTrackEvent", jest.fn(function () {
49
40
  _this.checkIdentifyCalled();
50
41
  }));
51
-
52
42
  _defineProperty(this, "sendPageEvent", jest.fn(function () {
53
43
  _this.checkIdentifyCalled();
54
44
  }));
55
-
56
45
  this.loggingService = loggingService;
57
46
  this.httpClient = httpClient;
58
47
  });
59
-
60
48
  _defineProperty(MockAnalyticsService, "hasIdentifyBeenCalled", false);
61
-
62
49
  export default MockAnalyticsService;
63
50
  //# sourceMappingURL=MockAnalyticsService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MockAnalyticsService.js","names":["MockAnalyticsService","httpClient","loggingService","jest","fn","hasIdentifyBeenCalled","logError","Promise","resolve","userId","Error","checkIdentifyCalled"],"sources":["../../src/analytics/MockAnalyticsService.js"],"sourcesContent":["/**\n * The MockAnalyticsService implements all functions of AnalyticsService as Jest mocks (jest.fn())).\n * It emulates the behavior of a real analytics service but witohut making any requests. It has no\n * other functionality.\n *\n * @implements {AnalyticsService}\n * @memberof module:Analytics\n */\nclass MockAnalyticsService {\n static hasIdentifyBeenCalled = false;\n\n constructor({ httpClient, loggingService }) {\n this.loggingService = loggingService;\n this.httpClient = httpClient;\n }\n\n checkIdentifyCalled = jest.fn(() => {\n if (!this.hasIdentifyBeenCalled) {\n this.loggingService.logError('Identify must be called before other tracking events.');\n }\n });\n\n /**\n * Returns a resolved promise.\n *\n * @returns {Promise} The promise returned by HttpClient.post.\n */\n sendTrackingLogEvent = jest.fn(() => Promise.resolve());\n\n /**\n * No-op, but records that identify has been called.\n *\n * @param {string} userId\n * @throws {Error} If userId argument is not supplied.\n */\n identifyAuthenticatedUser = jest.fn((userId) => {\n if (!userId) {\n throw new Error('UserId is required for identifyAuthenticatedUser.');\n }\n this.hasIdentifyBeenCalled = true;\n });\n\n /**\n * No-op, but records that it has been called to prevent double-identification.\n * @returns {Promise} A resolved promise.\n */\n identifyAnonymousUser = jest.fn(() => {\n this.hasIdentifyBeenCalled = true;\n return Promise.resolve();\n });\n\n /**\n * Logs the event to the console.\n *\n * Checks whether identify has been called, logging an error to the logging service if not.\n */\n sendTrackEvent = jest.fn(() => {\n this.checkIdentifyCalled();\n });\n\n /**\n * Logs the event to the console.\n *\n * Checks whether identify has been called, logging an error to the logging service if not.\n */\n sendPageEvent = jest.fn(() => {\n this.checkIdentifyCalled();\n });\n}\n\nexport default MockAnalyticsService;\n"],"mappings":";;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACMA,oB,6BAGJ,oCAA4C;EAAA;;EAAA,IAA9BC,UAA8B,QAA9BA,UAA8B;EAAA,IAAlBC,cAAkB,QAAlBA,cAAkB;;EAAA;;EAAA,6CAKtBC,IAAI,CAACC,EAAL,CAAQ,YAAM;IAClC,IAAI,CAAC,KAAI,CAACC,qBAAV,EAAiC;MAC/B,KAAI,CAACH,cAAL,CAAoBI,QAApB,CAA6B,uDAA7B;IACD;EACF,CAJqB,CALsB;;EAAA,8CAgBrBH,IAAI,CAACC,EAAL,CAAQ;IAAA,OAAMG,OAAO,CAACC,OAAR,EAAN;EAAA,CAAR,CAhBqB;;EAAA,mDAwBhBL,IAAI,CAACC,EAAL,CAAQ,UAACK,MAAD,EAAY;IAC9C,IAAI,CAACA,MAAL,EAAa;MACX,MAAM,IAAIC,KAAJ,CAAU,mDAAV,CAAN;IACD;;IACD,KAAI,CAACL,qBAAL,GAA6B,IAA7B;EACD,CAL2B,CAxBgB;;EAAA,+CAmCpBF,IAAI,CAACC,EAAL,CAAQ,YAAM;IACpC,KAAI,CAACC,qBAAL,GAA6B,IAA7B;IACA,OAAOE,OAAO,CAACC,OAAR,EAAP;EACD,CAHuB,CAnCoB;;EAAA,wCA6C3BL,IAAI,CAACC,EAAL,CAAQ,YAAM;IAC7B,KAAI,CAACO,mBAAL;EACD,CAFgB,CA7C2B;;EAAA,uCAsD5BR,IAAI,CAACC,EAAL,CAAQ,YAAM;IAC5B,KAAI,CAACO,mBAAL;EACD,CAFe,CAtD4B;;EAC1C,KAAKT,cAAL,GAAsBA,cAAtB;EACA,KAAKD,UAAL,GAAkBA,UAAlB;AACD,C;;gBANGD,oB,2BAC2B,K;;AA6DjC,eAAeA,oBAAf"}
1
+ {"version":3,"file":"MockAnalyticsService.js","names":["MockAnalyticsService","_createClass","_ref","_this","httpClient","loggingService","_classCallCheck","_defineProperty","jest","fn","hasIdentifyBeenCalled","logError","Promise","resolve","userId","Error","checkIdentifyCalled"],"sources":["../../src/analytics/MockAnalyticsService.js"],"sourcesContent":["/**\n * The MockAnalyticsService implements all functions of AnalyticsService as Jest mocks (jest.fn())).\n * It emulates the behavior of a real analytics service but witohut making any requests. It has no\n * other functionality.\n *\n * @implements {AnalyticsService}\n * @memberof module:Analytics\n */\nclass MockAnalyticsService {\n static hasIdentifyBeenCalled = false;\n\n constructor({ httpClient, loggingService }) {\n this.loggingService = loggingService;\n this.httpClient = httpClient;\n }\n\n checkIdentifyCalled = jest.fn(() => {\n if (!this.hasIdentifyBeenCalled) {\n this.loggingService.logError('Identify must be called before other tracking events.');\n }\n });\n\n /**\n * Returns a resolved promise.\n *\n * @returns {Promise} The promise returned by HttpClient.post.\n */\n sendTrackingLogEvent = jest.fn(() => Promise.resolve());\n\n /**\n * No-op, but records that identify has been called.\n *\n * @param {string} userId\n * @throws {Error} If userId argument is not supplied.\n */\n identifyAuthenticatedUser = jest.fn((userId) => {\n if (!userId) {\n throw new Error('UserId is required for identifyAuthenticatedUser.');\n }\n this.hasIdentifyBeenCalled = true;\n });\n\n /**\n * No-op, but records that it has been called to prevent double-identification.\n * @returns {Promise} A resolved promise.\n */\n identifyAnonymousUser = jest.fn(() => {\n this.hasIdentifyBeenCalled = true;\n return Promise.resolve();\n });\n\n /**\n * Logs the event to the console.\n *\n * Checks whether identify has been called, logging an error to the logging service if not.\n */\n sendTrackEvent = jest.fn(() => {\n this.checkIdentifyCalled();\n });\n\n /**\n * Logs the event to the console.\n *\n * Checks whether identify has been called, logging an error to the logging service if not.\n */\n sendPageEvent = jest.fn(() => {\n this.checkIdentifyCalled();\n });\n}\n\nexport default MockAnalyticsService;\n"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA,IAQMA,oBAAoB,gBAAAC,YAAA,CAGxB,SAAAD,qBAAAE,IAAA,EAA4C;EAAA,IAAAC,KAAA;EAAA,IAA9BC,UAAU,GAAAF,IAAA,CAAVE,UAAU;IAAEC,cAAc,GAAAH,IAAA,CAAdG,cAAc;EAAAC,eAAA,OAAAN,oBAAA;EAAAO,eAAA,8BAKlBC,IAAI,CAACC,EAAE,CAAC,YAAM;IAClC,IAAI,CAACN,KAAI,CAACO,qBAAqB,EAAE;MAC/BP,KAAI,CAACE,cAAc,CAACM,QAAQ,CAAC,uDAAuD,CAAC;IACvF;EACF,CAAC,CAAC;EAAAJ,eAAA,+BAOqBC,IAAI,CAACC,EAAE,CAAC;IAAA,OAAMG,OAAO,CAACC,OAAO,EAAE;EAAA,EAAC;EAAAN,eAAA,oCAQ3BC,IAAI,CAACC,EAAE,CAAC,UAACK,MAAM,EAAK;IAC9C,IAAI,CAACA,MAAM,EAAE;MACX,MAAM,IAAIC,KAAK,CAAC,mDAAmD,CAAC;IACtE;IACAZ,KAAI,CAACO,qBAAqB,GAAG,IAAI;EACnC,CAAC,CAAC;EAAAH,eAAA,gCAMsBC,IAAI,CAACC,EAAE,CAAC,YAAM;IACpCN,KAAI,CAACO,qBAAqB,GAAG,IAAI;IACjC,OAAOE,OAAO,CAACC,OAAO,EAAE;EAC1B,CAAC,CAAC;EAAAN,eAAA,yBAOeC,IAAI,CAACC,EAAE,CAAC,YAAM;IAC7BN,KAAI,CAACa,mBAAmB,EAAE;EAC5B,CAAC,CAAC;EAAAT,eAAA,wBAOcC,IAAI,CAACC,EAAE,CAAC,YAAM;IAC5BN,KAAI,CAACa,mBAAmB,EAAE;EAC5B,CAAC,CAAC;EAvDA,IAAI,CAACX,cAAc,GAAGA,cAAc;EACpC,IAAI,CAACD,UAAU,GAAGA,UAAU;AAC9B,CAAC;AAAAG,eAAA,CANGP,oBAAoB,2BACO,KAAK;AA6DtC,eAAeA,oBAAoB"}
@@ -1,122 +1,121 @@
1
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
1
2
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2
-
3
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
4
-
3
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
5
4
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
6
-
5
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
6
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
7
7
  import formurlencoded from 'form-urlencoded';
8
8
  import { snakeCaseObject } from '../utils';
9
+
9
10
  /**
10
11
  * @implements {AnalyticsService}
11
12
  * @memberof module:Analytics
12
13
  */
13
-
14
14
  var SegmentAnalyticsService = /*#__PURE__*/function () {
15
15
  function SegmentAnalyticsService(_ref) {
16
16
  var httpClient = _ref.httpClient,
17
- loggingService = _ref.loggingService,
18
- config = _ref.config;
19
-
17
+ loggingService = _ref.loggingService,
18
+ config = _ref.config;
20
19
  _classCallCheck(this, SegmentAnalyticsService);
21
-
22
20
  this.loggingService = loggingService;
23
21
  this.httpClient = httpClient;
24
22
  this.trackingLogApiUrl = "".concat(config.LMS_BASE_URL, "/event");
25
23
  this.segmentKey = config.SEGMENT_KEY;
26
24
  this.hasIdentifyBeenCalled = false;
27
25
  this.segmentInitialized = false;
28
-
29
26
  if (this.segmentKey) {
30
27
  this.initializeSegment();
31
28
  }
32
- } // The code in this function is from Segment's website, with a few updates:
29
+ }
30
+
31
+ // The code in this function is from Segment's website, with a few updates:
33
32
  // - It uses the segmentKey from the SegmentAnalyticsService instance.
34
33
  // - It also saves a "segmentInitialized" variable on the SegmentAnalyticsService instance so
35
34
  // that the service can keep track of its own initialization state.
36
35
  // Reference:
37
36
  // https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/quickstart/
38
-
39
-
40
37
  _createClass(SegmentAnalyticsService, [{
41
38
  key: "initializeSegment",
42
39
  value: function initializeSegment() {
43
40
  var _this = this;
44
-
45
41
  // Create a queue, but don't obliterate an existing one!
46
42
  global.analytics = global.analytics || [];
47
43
  var _global = global,
48
- analytics = _global.analytics; // If the real analytics.js is already on the page return.
44
+ analytics = _global.analytics;
49
45
 
46
+ // If the real analytics.js is already on the page return.
50
47
  if (analytics.initialize) {
51
48
  this.segmentInitialized = true;
52
49
  return;
53
- } // If the snippet was invoked do nothing.
54
-
50
+ }
55
51
 
52
+ // If the snippet was invoked do nothing.
56
53
  if (analytics.invoked) {
57
54
  this.segmentInitialized = true;
58
55
  return;
59
- } // Invoked flag, to make sure the snippet
60
- // is never invoked twice.
56
+ }
61
57
 
58
+ // Invoked flag, to make sure the snippet
59
+ // is never invoked twice.
60
+ analytics.invoked = true;
62
61
 
63
- analytics.invoked = true; // A list of the methods in Analytics.js to stub.
62
+ // A list of the methods in Analytics.js to stub.
63
+ analytics.methods = ['trackSubmit', 'trackClick', 'trackLink', 'trackForm', 'pageview', 'identify', 'reset', 'group', 'track', 'ready', 'alias', 'debug', 'page', 'once', 'off', 'on'];
64
64
 
65
- analytics.methods = ['trackSubmit', 'trackClick', 'trackLink', 'trackForm', 'pageview', 'identify', 'reset', 'group', 'track', 'ready', 'alias', 'debug', 'page', 'once', 'off', 'on']; // Define a factory to create stubs. These are placeholders
65
+ // Define a factory to create stubs. These are placeholders
66
66
  // for methods in Analytics.js so that you never have to wait
67
67
  // for it to load to actually record data. The `method` is
68
68
  // stored as the first argument, so we can replay the data.
69
-
70
69
  analytics.factory = function (method) {
71
70
  return function () {
72
71
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
73
72
  args[_key] = arguments[_key];
74
73
  }
75
-
76
74
  args.unshift(method);
77
75
  analytics.push(args);
78
76
  return analytics;
79
77
  };
80
- }; // For each of our methods, generate a queueing stub.
81
-
78
+ };
82
79
 
80
+ // For each of our methods, generate a queueing stub.
83
81
  analytics.methods.forEach(function (key) {
84
82
  analytics[key] = analytics.factory(key);
85
- }); // Define a method to load Analytics.js from our CDN,
86
- // and that will be sure to only ever load it once.
83
+ });
87
84
 
85
+ // Define a method to load Analytics.js from our CDN,
86
+ // and that will be sure to only ever load it once.
88
87
  analytics.load = function (key, options) {
89
88
  // Create an async script element based on your key.
90
89
  var script = document.createElement('script');
91
90
  script.type = 'text/javascript';
92
-
93
91
  script.onerror = function () {
94
92
  _this.segmentInitialized = false;
95
93
  var event = new Event('segmentFailed');
96
94
  document.dispatchEvent(event);
97
95
  };
98
-
99
96
  script.async = true;
100
- script.src = "https://cdn.segment.com/analytics.js/v1/".concat(key, "/analytics.min.js"); // Insert our script next to the first script element.
97
+ script.src = "https://cdn.segment.com/analytics.js/v1/".concat(key, "/analytics.min.js");
101
98
 
99
+ // Insert our script next to the first script element.
102
100
  var first = document.getElementsByTagName('script')[0];
103
101
  first.parentNode.insertBefore(script, first);
104
102
  analytics._loadOptions = options; // eslint-disable-line no-underscore-dangle
105
103
 
106
104
  _this.segmentInitialized = true;
107
- }; // Add a version to keep track of what's in the wild.
105
+ };
108
106
 
107
+ // Add a version to keep track of what's in the wild.
108
+ analytics.SNIPPET_VERSION = '4.1.0';
109
109
 
110
- analytics.SNIPPET_VERSION = '4.1.0'; // Load Analytics.js with your key, which will automatically
110
+ // Load Analytics.js with your key, which will automatically
111
111
  // load the tools you've enabled for your account. Boosh!
112
-
113
112
  analytics.load(this.segmentKey);
114
113
  }
114
+
115
115
  /**
116
116
  * Checks that identify was first called. Otherwise, logs error.
117
117
  *
118
118
  */
119
-
120
119
  }, {
121
120
  key: "checkIdentifyCalled",
122
121
  value: function checkIdentifyCalled() {
@@ -124,6 +123,7 @@ var SegmentAnalyticsService = /*#__PURE__*/function () {
124
123
  this.loggingService.logError('Identify must be called before other tracking events.');
125
124
  }
126
125
  }
126
+
127
127
  /**
128
128
  * Logs events to tracking log and downstream.
129
129
  * For tracking log event documentation, see
@@ -133,12 +133,10 @@ var SegmentAnalyticsService = /*#__PURE__*/function () {
133
133
  * @param {Object} properties (event on backend, but named properties to match Segment api)
134
134
  * @returns {Promise} The promise returned by HttpClient.post.
135
135
  */
136
-
137
136
  }, {
138
137
  key: "sendTrackingLogEvent",
139
138
  value: function sendTrackingLogEvent(eventName, properties) {
140
139
  var _this2 = this;
141
-
142
140
  var snakeEventData = snakeCaseObject(properties, {
143
141
  deep: true
144
142
  });
@@ -155,67 +153,69 @@ var SegmentAnalyticsService = /*#__PURE__*/function () {
155
153
  _this2.loggingService.logError(error);
156
154
  });
157
155
  }
156
+
158
157
  /**
159
158
  * * Send identify call to Segment.
160
159
  *
161
160
  * @param {string} userId
162
161
  * @param {*} [traits]
163
162
  */
164
-
165
163
  }, {
166
164
  key: "identifyAuthenticatedUser",
167
165
  value: function identifyAuthenticatedUser(userId, traits) {
166
+ if (this.hasIdentifyBeenCalled) {
167
+ return;
168
+ }
168
169
  if (!userId) {
169
170
  throw new Error('UserId is required for identifyAuthenticatedUser.');
170
171
  }
171
-
172
172
  if (!this.segmentInitialized) {
173
173
  return;
174
174
  }
175
-
176
175
  global.analytics.identify(userId, traits);
177
176
  this.hasIdentifyBeenCalled = true;
178
177
  }
178
+
179
179
  /**
180
180
  * Send anonymous identify call to Segment's identify.
181
181
  *
182
182
  * @param {*} [traits]
183
183
  * @returns {Promise} Promise that will resolve once the document readyState is complete
184
184
  */
185
-
186
185
  }, {
187
186
  key: "identifyAnonymousUser",
188
187
  value: function identifyAnonymousUser(traits) {
189
188
  var _this3 = this;
190
-
191
189
  // eslint-disable-line no-unused-vars
190
+ if (this.hasIdentifyBeenCalled) {
191
+ return Promise.resolve();
192
+ }
192
193
  if (!this.segmentInitialized) {
193
194
  return Promise.resolve();
194
- } // if we do not have an authenticated user (indicated by being in this method),
195
+ }
196
+ // if we do not have an authenticated user (indicated by being in this method),
195
197
  // but we still have a user id associated in segment, reset the local segment state
196
198
  // This has to be wrapped in the analytics.ready() callback because the analytics.user()
197
199
  // function isn't available until the analytics.js package has finished initializing.
198
-
199
-
200
200
  return new Promise(function (resolve, reject) {
201
201
  // eslint-disable-line no-unused-vars
202
202
  global.analytics.ready(function () {
203
203
  if (global.analytics.user().id()) {
204
204
  global.analytics.reset();
205
- } // We don’t need to call `identify` for anonymous users and can just make the value of
205
+ }
206
+ // We don’t need to call `identify` for anonymous users and can just make the value of
206
207
  // hasIdentifyBeenCalled true. Segment automatically assigns them an anonymousId, so
207
208
  // just calling `page` and `track` works fine without identify.
208
-
209
-
210
209
  _this3.hasIdentifyBeenCalled = true;
211
210
  resolve();
212
- }); // this is added to handle a specific use-case where if a user has blocked the analytics
211
+ });
212
+
213
+ // this is added to handle a specific use-case where if a user has blocked the analytics
213
214
  // tools in their browser, this promise does not get resolved and user sees a blank
214
215
  // page. Dispatching this event in script.onerror callback in analytics.load.
215
-
216
- document.addEventListener('segmentFailed', resolve); // This is added to handle the google analytics blocked case which is injected into
216
+ document.addEventListener('segmentFailed', resolve);
217
+ // This is added to handle the google analytics blocked case which is injected into
217
218
  // the DOM by segment.min.js.
218
-
219
219
  setTimeout(function () {
220
220
  if (!global.ga || !global.ga.create || !global.google_tag_manager) {
221
221
  _this3.segmentInitialized = false;
@@ -224,6 +224,7 @@ var SegmentAnalyticsService = /*#__PURE__*/function () {
224
224
  }, 2000);
225
225
  });
226
226
  }
227
+
227
228
  /**
228
229
  * Sends a track event to Segment and downstream.
229
230
  * Note: For links and forms, you should use trackLink and trackForm instead.
@@ -231,17 +232,16 @@ var SegmentAnalyticsService = /*#__PURE__*/function () {
231
232
  * @param {*} eventName
232
233
  * @param {*} [properties]
233
234
  */
234
-
235
235
  }, {
236
236
  key: "sendTrackEvent",
237
237
  value: function sendTrackEvent(eventName, properties) {
238
238
  if (!this.segmentInitialized) {
239
239
  return;
240
240
  }
241
-
242
241
  this.checkIdentifyCalled();
243
242
  global.analytics.track(eventName, properties);
244
243
  }
244
+
245
245
  /**
246
246
  * Sends a page event to Segment and downstream.
247
247
  *
@@ -249,21 +249,17 @@ var SegmentAnalyticsService = /*#__PURE__*/function () {
249
249
  * @param {*} [category] Name is required to pass a category.
250
250
  * @param {*} [properties]
251
251
  */
252
-
253
252
  }, {
254
253
  key: "sendPageEvent",
255
254
  value: function sendPageEvent(category, name, properties) {
256
255
  if (!this.segmentInitialized) {
257
256
  return;
258
257
  }
259
-
260
258
  this.checkIdentifyCalled();
261
259
  global.analytics.page(category, name, properties);
262
260
  }
263
261
  }]);
264
-
265
262
  return SegmentAnalyticsService;
266
263
  }();
267
-
268
264
  export default SegmentAnalyticsService;
269
265
  //# sourceMappingURL=SegmentAnalyticsService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentAnalyticsService.js","names":["formurlencoded","snakeCaseObject","SegmentAnalyticsService","httpClient","loggingService","config","trackingLogApiUrl","LMS_BASE_URL","segmentKey","SEGMENT_KEY","hasIdentifyBeenCalled","segmentInitialized","initializeSegment","global","analytics","initialize","invoked","methods","factory","method","args","unshift","push","forEach","key","load","options","script","document","createElement","type","onerror","event","Event","dispatchEvent","async","src","first","getElementsByTagName","parentNode","insertBefore","_loadOptions","SNIPPET_VERSION","logError","eventName","properties","snakeEventData","deep","serverData","event_type","JSON","stringify","page","location","href","post","headers","error","userId","traits","Error","identify","Promise","resolve","reject","ready","user","id","reset","addEventListener","setTimeout","ga","create","google_tag_manager","checkIdentifyCalled","track","category","name"],"sources":["../../src/analytics/SegmentAnalyticsService.js"],"sourcesContent":["import formurlencoded from 'form-urlencoded';\nimport { snakeCaseObject } from '../utils';\n\n/**\n * @implements {AnalyticsService}\n * @memberof module:Analytics\n */\nclass SegmentAnalyticsService {\n constructor({ httpClient, loggingService, config }) {\n this.loggingService = loggingService;\n this.httpClient = httpClient;\n this.trackingLogApiUrl = `${config.LMS_BASE_URL}/event`;\n this.segmentKey = config.SEGMENT_KEY;\n this.hasIdentifyBeenCalled = false;\n this.segmentInitialized = false;\n\n if (this.segmentKey) {\n this.initializeSegment();\n }\n }\n\n // The code in this function is from Segment's website, with a few updates:\n // - It uses the segmentKey from the SegmentAnalyticsService instance.\n // - It also saves a \"segmentInitialized\" variable on the SegmentAnalyticsService instance so\n // that the service can keep track of its own initialization state.\n // Reference:\n // https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/quickstart/\n initializeSegment() {\n // Create a queue, but don't obliterate an existing one!\n global.analytics = global.analytics || [];\n const { analytics } = global;\n\n // If the real analytics.js is already on the page return.\n if (analytics.initialize) {\n this.segmentInitialized = true;\n return;\n }\n\n // If the snippet was invoked do nothing.\n if (analytics.invoked) {\n this.segmentInitialized = true;\n return;\n }\n\n // Invoked flag, to make sure the snippet\n // is never invoked twice.\n analytics.invoked = true;\n\n // A list of the methods in Analytics.js to stub.\n analytics.methods = [\n 'trackSubmit',\n 'trackClick',\n 'trackLink',\n 'trackForm',\n 'pageview',\n 'identify',\n 'reset',\n 'group',\n 'track',\n 'ready',\n 'alias',\n 'debug',\n 'page',\n 'once',\n 'off',\n 'on',\n ];\n\n // Define a factory to create stubs. These are placeholders\n // for methods in Analytics.js so that you never have to wait\n // for it to load to actually record data. The `method` is\n // stored as the first argument, so we can replay the data.\n analytics.factory = method => ((...args) => {\n args.unshift(method);\n analytics.push(args);\n return analytics;\n });\n\n // For each of our methods, generate a queueing stub.\n analytics.methods.forEach((key) => {\n analytics[key] = analytics.factory(key);\n });\n\n // Define a method to load Analytics.js from our CDN,\n // and that will be sure to only ever load it once.\n analytics.load = (key, options) => {\n // Create an async script element based on your key.\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.onerror = () => {\n this.segmentInitialized = false;\n const event = new Event('segmentFailed');\n document.dispatchEvent(event);\n };\n script.async = true;\n script.src = `https://cdn.segment.com/analytics.js/v1/${key}/analytics.min.js`;\n\n // Insert our script next to the first script element.\n const first = document.getElementsByTagName('script')[0];\n first.parentNode.insertBefore(script, first);\n analytics._loadOptions = options; // eslint-disable-line no-underscore-dangle\n\n this.segmentInitialized = true;\n };\n\n // Add a version to keep track of what's in the wild.\n analytics.SNIPPET_VERSION = '4.1.0';\n\n // Load Analytics.js with your key, which will automatically\n // load the tools you've enabled for your account. Boosh!\n analytics.load(this.segmentKey);\n }\n\n /**\n * Checks that identify was first called. Otherwise, logs error.\n *\n */\n checkIdentifyCalled() {\n if (!this.hasIdentifyBeenCalled) {\n this.loggingService.logError('Identify must be called before other tracking events.');\n }\n }\n\n /**\n * Logs events to tracking log and downstream.\n * For tracking log event documentation, see\n * https://openedx.atlassian.net/wiki/spaces/AN/pages/13205895/Event+Design+and+Review+Process\n *\n * @param {string} eventName (event_type on backend, but named to match Segment api)\n * @param {Object} properties (event on backend, but named properties to match Segment api)\n * @returns {Promise} The promise returned by HttpClient.post.\n */\n sendTrackingLogEvent(eventName, properties) {\n const snakeEventData = snakeCaseObject(properties, { deep: true });\n const serverData = {\n event_type: eventName,\n event: JSON.stringify(snakeEventData),\n page: global.location.href,\n };\n return this.httpClient.post(\n this.trackingLogApiUrl,\n formurlencoded(serverData),\n {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n },\n ).catch((error) => {\n this.loggingService.logError(error);\n });\n }\n\n /**\n * * Send identify call to Segment.\n *\n * @param {string} userId\n * @param {*} [traits]\n */\n identifyAuthenticatedUser(userId, traits) {\n if (!userId) {\n throw new Error('UserId is required for identifyAuthenticatedUser.');\n }\n\n if (!this.segmentInitialized) {\n return;\n }\n global.analytics.identify(userId, traits);\n this.hasIdentifyBeenCalled = true;\n }\n\n /**\n * Send anonymous identify call to Segment's identify.\n *\n * @param {*} [traits]\n * @returns {Promise} Promise that will resolve once the document readyState is complete\n */\n identifyAnonymousUser(traits) { // eslint-disable-line no-unused-vars\n if (!this.segmentInitialized) {\n return Promise.resolve();\n }\n // if we do not have an authenticated user (indicated by being in this method),\n // but we still have a user id associated in segment, reset the local segment state\n // This has to be wrapped in the analytics.ready() callback because the analytics.user()\n // function isn't available until the analytics.js package has finished initializing.\n return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars\n global.analytics.ready(() => {\n if (global.analytics.user().id()) {\n global.analytics.reset();\n }\n // We don’t need to call `identify` for anonymous users and can just make the value of\n // hasIdentifyBeenCalled true. Segment automatically assigns them an anonymousId, so\n // just calling `page` and `track` works fine without identify.\n this.hasIdentifyBeenCalled = true;\n resolve();\n });\n\n // this is added to handle a specific use-case where if a user has blocked the analytics\n // tools in their browser, this promise does not get resolved and user sees a blank\n // page. Dispatching this event in script.onerror callback in analytics.load.\n document.addEventListener('segmentFailed', resolve);\n // This is added to handle the google analytics blocked case which is injected into\n // the DOM by segment.min.js.\n setTimeout(() => {\n if (!global.ga || !global.ga.create || !global.google_tag_manager) {\n this.segmentInitialized = false;\n resolve();\n }\n }, 2000);\n });\n }\n\n /**\n * Sends a track event to Segment and downstream.\n * Note: For links and forms, you should use trackLink and trackForm instead.\n *\n * @param {*} eventName\n * @param {*} [properties]\n */\n sendTrackEvent(eventName, properties) {\n if (!this.segmentInitialized) {\n return;\n }\n this.checkIdentifyCalled();\n global.analytics.track(eventName, properties);\n }\n\n /**\n * Sends a page event to Segment and downstream.\n *\n * @param {*} [name] If only one string arg provided, assumed to be name.\n * @param {*} [category] Name is required to pass a category.\n * @param {*} [properties]\n */\n sendPageEvent(category, name, properties) {\n if (!this.segmentInitialized) {\n return;\n }\n this.checkIdentifyCalled();\n global.analytics.page(category, name, properties);\n }\n}\n\nexport default SegmentAnalyticsService;\n"],"mappings":"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"}
1
+ {"version":3,"file":"SegmentAnalyticsService.js","names":["formurlencoded","snakeCaseObject","SegmentAnalyticsService","_ref","httpClient","loggingService","config","_classCallCheck","trackingLogApiUrl","concat","LMS_BASE_URL","segmentKey","SEGMENT_KEY","hasIdentifyBeenCalled","segmentInitialized","initializeSegment","_createClass","key","value","_this","global","analytics","_global","initialize","invoked","methods","factory","method","_len","arguments","length","args","Array","_key","unshift","push","forEach","load","options","script","document","createElement","type","onerror","event","Event","dispatchEvent","async","src","first","getElementsByTagName","parentNode","insertBefore","_loadOptions","SNIPPET_VERSION","checkIdentifyCalled","logError","sendTrackingLogEvent","eventName","properties","_this2","snakeEventData","deep","serverData","event_type","JSON","stringify","page","location","href","post","headers","error","identifyAuthenticatedUser","userId","traits","Error","identify","identifyAnonymousUser","_this3","Promise","resolve","reject","ready","user","id","reset","addEventListener","setTimeout","ga","create","google_tag_manager","sendTrackEvent","track","sendPageEvent","category","name"],"sources":["../../src/analytics/SegmentAnalyticsService.js"],"sourcesContent":["import formurlencoded from 'form-urlencoded';\nimport { snakeCaseObject } from '../utils';\n\n/**\n * @implements {AnalyticsService}\n * @memberof module:Analytics\n */\nclass SegmentAnalyticsService {\n constructor({ httpClient, loggingService, config }) {\n this.loggingService = loggingService;\n this.httpClient = httpClient;\n this.trackingLogApiUrl = `${config.LMS_BASE_URL}/event`;\n this.segmentKey = config.SEGMENT_KEY;\n this.hasIdentifyBeenCalled = false;\n this.segmentInitialized = false;\n\n if (this.segmentKey) {\n this.initializeSegment();\n }\n }\n\n // The code in this function is from Segment's website, with a few updates:\n // - It uses the segmentKey from the SegmentAnalyticsService instance.\n // - It also saves a \"segmentInitialized\" variable on the SegmentAnalyticsService instance so\n // that the service can keep track of its own initialization state.\n // Reference:\n // https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/quickstart/\n initializeSegment() {\n // Create a queue, but don't obliterate an existing one!\n global.analytics = global.analytics || [];\n const { analytics } = global;\n\n // If the real analytics.js is already on the page return.\n if (analytics.initialize) {\n this.segmentInitialized = true;\n return;\n }\n\n // If the snippet was invoked do nothing.\n if (analytics.invoked) {\n this.segmentInitialized = true;\n return;\n }\n\n // Invoked flag, to make sure the snippet\n // is never invoked twice.\n analytics.invoked = true;\n\n // A list of the methods in Analytics.js to stub.\n analytics.methods = [\n 'trackSubmit',\n 'trackClick',\n 'trackLink',\n 'trackForm',\n 'pageview',\n 'identify',\n 'reset',\n 'group',\n 'track',\n 'ready',\n 'alias',\n 'debug',\n 'page',\n 'once',\n 'off',\n 'on',\n ];\n\n // Define a factory to create stubs. These are placeholders\n // for methods in Analytics.js so that you never have to wait\n // for it to load to actually record data. The `method` is\n // stored as the first argument, so we can replay the data.\n analytics.factory = method => ((...args) => {\n args.unshift(method);\n analytics.push(args);\n return analytics;\n });\n\n // For each of our methods, generate a queueing stub.\n analytics.methods.forEach((key) => {\n analytics[key] = analytics.factory(key);\n });\n\n // Define a method to load Analytics.js from our CDN,\n // and that will be sure to only ever load it once.\n analytics.load = (key, options) => {\n // Create an async script element based on your key.\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.onerror = () => {\n this.segmentInitialized = false;\n const event = new Event('segmentFailed');\n document.dispatchEvent(event);\n };\n script.async = true;\n script.src = `https://cdn.segment.com/analytics.js/v1/${key}/analytics.min.js`;\n\n // Insert our script next to the first script element.\n const first = document.getElementsByTagName('script')[0];\n first.parentNode.insertBefore(script, first);\n analytics._loadOptions = options; // eslint-disable-line no-underscore-dangle\n\n this.segmentInitialized = true;\n };\n\n // Add a version to keep track of what's in the wild.\n analytics.SNIPPET_VERSION = '4.1.0';\n\n // Load Analytics.js with your key, which will automatically\n // load the tools you've enabled for your account. Boosh!\n analytics.load(this.segmentKey);\n }\n\n /**\n * Checks that identify was first called. Otherwise, logs error.\n *\n */\n checkIdentifyCalled() {\n if (!this.hasIdentifyBeenCalled) {\n this.loggingService.logError('Identify must be called before other tracking events.');\n }\n }\n\n /**\n * Logs events to tracking log and downstream.\n * For tracking log event documentation, see\n * https://openedx.atlassian.net/wiki/spaces/AN/pages/13205895/Event+Design+and+Review+Process\n *\n * @param {string} eventName (event_type on backend, but named to match Segment api)\n * @param {Object} properties (event on backend, but named properties to match Segment api)\n * @returns {Promise} The promise returned by HttpClient.post.\n */\n sendTrackingLogEvent(eventName, properties) {\n const snakeEventData = snakeCaseObject(properties, { deep: true });\n const serverData = {\n event_type: eventName,\n event: JSON.stringify(snakeEventData),\n page: global.location.href,\n };\n return this.httpClient.post(\n this.trackingLogApiUrl,\n formurlencoded(serverData),\n {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n },\n ).catch((error) => {\n this.loggingService.logError(error);\n });\n }\n\n /**\n * * Send identify call to Segment.\n *\n * @param {string} userId\n * @param {*} [traits]\n */\n identifyAuthenticatedUser(userId, traits) {\n if (this.hasIdentifyBeenCalled) {\n return;\n }\n\n if (!userId) {\n throw new Error('UserId is required for identifyAuthenticatedUser.');\n }\n\n if (!this.segmentInitialized) {\n return;\n }\n global.analytics.identify(userId, traits);\n this.hasIdentifyBeenCalled = true;\n }\n\n /**\n * Send anonymous identify call to Segment's identify.\n *\n * @param {*} [traits]\n * @returns {Promise} Promise that will resolve once the document readyState is complete\n */\n identifyAnonymousUser(traits) { // eslint-disable-line no-unused-vars\n if (this.hasIdentifyBeenCalled) {\n return Promise.resolve();\n }\n\n if (!this.segmentInitialized) {\n return Promise.resolve();\n }\n // if we do not have an authenticated user (indicated by being in this method),\n // but we still have a user id associated in segment, reset the local segment state\n // This has to be wrapped in the analytics.ready() callback because the analytics.user()\n // function isn't available until the analytics.js package has finished initializing.\n return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars\n global.analytics.ready(() => {\n if (global.analytics.user().id()) {\n global.analytics.reset();\n }\n // We don’t need to call `identify` for anonymous users and can just make the value of\n // hasIdentifyBeenCalled true. Segment automatically assigns them an anonymousId, so\n // just calling `page` and `track` works fine without identify.\n this.hasIdentifyBeenCalled = true;\n resolve();\n });\n\n // this is added to handle a specific use-case where if a user has blocked the analytics\n // tools in their browser, this promise does not get resolved and user sees a blank\n // page. Dispatching this event in script.onerror callback in analytics.load.\n document.addEventListener('segmentFailed', resolve);\n // This is added to handle the google analytics blocked case which is injected into\n // the DOM by segment.min.js.\n setTimeout(() => {\n if (!global.ga || !global.ga.create || !global.google_tag_manager) {\n this.segmentInitialized = false;\n resolve();\n }\n }, 2000);\n });\n }\n\n /**\n * Sends a track event to Segment and downstream.\n * Note: For links and forms, you should use trackLink and trackForm instead.\n *\n * @param {*} eventName\n * @param {*} [properties]\n */\n sendTrackEvent(eventName, properties) {\n if (!this.segmentInitialized) {\n return;\n }\n this.checkIdentifyCalled();\n global.analytics.track(eventName, properties);\n }\n\n /**\n * Sends a page event to Segment and downstream.\n *\n * @param {*} [name] If only one string arg provided, assumed to be name.\n * @param {*} [category] Name is required to pass a category.\n * @param {*} [properties]\n */\n sendPageEvent(category, name, properties) {\n if (!this.segmentInitialized) {\n return;\n }\n this.checkIdentifyCalled();\n global.analytics.page(category, name, properties);\n }\n}\n\nexport default SegmentAnalyticsService;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["configure","identifyAnonymousUser","identifyAuthenticatedUser","sendPageEvent","sendTrackEvent","sendTrackingLogEvent","getAnalyticsService","resetAnalyticsService","default","SegmentAnalyticsService","MockAnalyticsService"],"sources":["../../src/analytics/index.js"],"sourcesContent":["export {\n configure,\n identifyAnonymousUser,\n identifyAuthenticatedUser,\n sendPageEvent,\n sendTrackEvent,\n sendTrackingLogEvent,\n getAnalyticsService,\n resetAnalyticsService,\n} from './interface';\nexport { default as SegmentAnalyticsService } from './SegmentAnalyticsService';\nexport { default as MockAnalyticsService } from './MockAnalyticsService';\n"],"mappings":"AAAA,SACEA,SADF,EAEEC,qBAFF,EAGEC,yBAHF,EAIEC,aAJF,EAKEC,cALF,EAMEC,oBANF,EAOEC,mBAPF,EAQEC,qBARF,QASO,aATP;AAUA,SAASC,OAAO,IAAIC,uBAApB,QAAmD,2BAAnD;AACA,SAASD,OAAO,IAAIE,oBAApB,QAAgD,wBAAhD"}
1
+ {"version":3,"file":"index.js","names":["configure","identifyAnonymousUser","identifyAuthenticatedUser","sendPageEvent","sendTrackEvent","sendTrackingLogEvent","getAnalyticsService","resetAnalyticsService","default","SegmentAnalyticsService","MockAnalyticsService"],"sources":["../../src/analytics/index.js"],"sourcesContent":["export {\n configure,\n identifyAnonymousUser,\n identifyAuthenticatedUser,\n sendPageEvent,\n sendTrackEvent,\n sendTrackingLogEvent,\n getAnalyticsService,\n resetAnalyticsService,\n} from './interface';\nexport { default as SegmentAnalyticsService } from './SegmentAnalyticsService';\nexport { default as MockAnalyticsService } from './MockAnalyticsService';\n"],"mappings":"AAAA,SACEA,SAAS,EACTC,qBAAqB,EACrBC,yBAAyB,EACzBC,aAAa,EACbC,cAAc,EACdC,oBAAoB,EACpBC,mBAAmB,EACnBC,qBAAqB,QAChB,aAAa;AACpB,SAASC,OAAO,IAAIC,uBAAuB,QAAQ,2BAA2B;AAC9E,SAASD,OAAO,IAAIE,oBAAoB,QAAQ,wBAAwB"}
@@ -42,59 +42,60 @@ var serviceShape = {
42
42
  sendPageEvent: PropTypes.func.isRequired
43
43
  };
44
44
  var service;
45
+
45
46
  /**
46
47
  *
47
48
  * @param {class} AnalyticsService
48
49
  * @param {*} options
49
50
  * @returns {AnalyticsService}
50
51
  */
51
-
52
52
  export function configure(AnalyticsService, options) {
53
53
  PropTypes.checkPropTypes(optionsShape, options, 'property', 'Analytics');
54
54
  service = new AnalyticsService(options);
55
55
  PropTypes.checkPropTypes(serviceShape, service, 'property', 'AnalyticsService');
56
56
  return service;
57
57
  }
58
+
58
59
  /**
59
60
  *
60
61
  * @param {*} eventName
61
62
  * @param {*} properties
62
63
  * @returns {Promise}
63
64
  */
64
-
65
65
  export function sendTrackingLogEvent(eventName, properties) {
66
66
  return service.sendTrackingLogEvent(eventName, properties);
67
67
  }
68
+
68
69
  /**
69
70
  *
70
71
  *
71
72
  * @param {*} userId
72
73
  * @param {*} traits
73
74
  */
74
-
75
75
  export function identifyAuthenticatedUser(userId, traits) {
76
76
  service.identifyAuthenticatedUser(userId, traits);
77
77
  }
78
+
78
79
  /**
79
80
  *
80
81
  *
81
82
  * @param {*} traits
82
83
  * @returns {Promise}
83
84
  */
84
-
85
85
  export function identifyAnonymousUser(traits) {
86
86
  return service.identifyAnonymousUser(traits);
87
87
  }
88
+
88
89
  /**
89
90
  *
90
91
  *
91
92
  * @param {*} eventName
92
93
  * @param {*} properties
93
94
  */
94
-
95
95
  export function sendTrackEvent(eventName, properties) {
96
96
  service.sendTrackEvent(eventName, properties);
97
97
  }
98
+
98
99
  /**
99
100
  *
100
101
  *
@@ -102,30 +103,29 @@ export function sendTrackEvent(eventName, properties) {
102
103
  * @param {*} name
103
104
  * @param {*} properties
104
105
  */
105
-
106
106
  export function sendPageEvent(category, name, properties) {
107
107
  service.sendPageEvent(category, name, properties);
108
108
  }
109
+
109
110
  /**
110
111
  *
111
112
  *
112
113
  * @returns {AnalyticsService}
113
114
  */
114
-
115
115
  export function getAnalyticsService() {
116
116
  if (!service) {
117
117
  throw Error('You must first configure the analytics service.');
118
118
  }
119
-
120
119
  return service;
121
120
  }
121
+
122
122
  /**
123
123
  *
124
124
  */
125
-
126
125
  export function resetAnalyticsService() {
127
126
  service = null;
128
127
  }
128
+
129
129
  /**
130
130
  * @name AnalyticsService
131
131
  * @interface
@@ -1 +1 @@
1
- {"version":3,"file":"interface.js","names":["PropTypes","optionsShape","config","object","isRequired","httpClient","oneOfType","func","loggingService","shape","logError","logInfo","serviceShape","sendTrackingLogEvent","identifyAuthenticatedUser","identifyAnonymousUser","sendTrackEvent","sendPageEvent","service","configure","AnalyticsService","options","checkPropTypes","eventName","properties","userId","traits","category","name","getAnalyticsService","Error","resetAnalyticsService"],"sources":["../../src/analytics/interface.js"],"sourcesContent":["/**\n * #### Import members from **@edx/frontend-platform/analytics**\n *\n * Contains a shared interface for tracking events. Has a default implementation of\n * SegmentAnalyticsService, which supports Segment and the Tracking Log API (hosted in LMS).\n *\n * The `initialize` function performs much of the analytics configuration for you. If, however,\n * you're not using the `initialize` function, analytics can be configured via:\n *\n * ```\n * import { configure, SegmentAnalyticsService } from '@edx/frontend-platform/analytics';\n * import { getConfig } from '@edx/frontend-platform';\n * import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';\n * import { getLoggingService } from '@edx/frontend-platform/logging';\n *\n * configure(SegmentAnalyticsService, {\n * config: getConfig(),\n * loggingService: getLoggingService(),\n * httpClient: getAuthenticatedHttpClient(),\n * });\n * ```\n *\n * As shown in this example, analytics depends on the configuration document, logging, and having\n * an authenticated HTTP client.\n *\n * @module Analytics\n */\nimport PropTypes from 'prop-types';\n\nconst optionsShape = {\n config: PropTypes.object.isRequired,\n httpClient: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired,\n loggingService: PropTypes.shape({\n logError: PropTypes.func.isRequired,\n logInfo: PropTypes.func.isRequired,\n }).isRequired,\n};\n\nconst serviceShape = {\n sendTrackingLogEvent: PropTypes.func.isRequired,\n identifyAuthenticatedUser: PropTypes.func.isRequired,\n identifyAnonymousUser: PropTypes.func.isRequired,\n sendTrackEvent: PropTypes.func.isRequired,\n sendPageEvent: PropTypes.func.isRequired,\n};\n\nlet service;\n\n/**\n *\n * @param {class} AnalyticsService\n * @param {*} options\n * @returns {AnalyticsService}\n */\nexport function configure(AnalyticsService, options) {\n PropTypes.checkPropTypes(optionsShape, options, 'property', 'Analytics');\n service = new AnalyticsService(options);\n PropTypes.checkPropTypes(serviceShape, service, 'property', 'AnalyticsService');\n return service;\n}\n\n/**\n *\n * @param {*} eventName\n * @param {*} properties\n * @returns {Promise}\n */\nexport function sendTrackingLogEvent(eventName, properties) {\n return service.sendTrackingLogEvent(eventName, properties);\n}\n\n/**\n *\n *\n * @param {*} userId\n * @param {*} traits\n */\nexport function identifyAuthenticatedUser(userId, traits) {\n service.identifyAuthenticatedUser(userId, traits);\n}\n\n/**\n *\n *\n * @param {*} traits\n * @returns {Promise}\n */\nexport function identifyAnonymousUser(traits) {\n return service.identifyAnonymousUser(traits);\n}\n\n/**\n *\n *\n * @param {*} eventName\n * @param {*} properties\n */\nexport function sendTrackEvent(eventName, properties) {\n service.sendTrackEvent(eventName, properties);\n}\n\n/**\n *\n *\n * @param {*} category\n * @param {*} name\n * @param {*} properties\n */\nexport function sendPageEvent(category, name, properties) {\n service.sendPageEvent(category, name, properties);\n}\n\n/**\n *\n *\n * @returns {AnalyticsService}\n */\nexport function getAnalyticsService() {\n if (!service) {\n throw Error('You must first configure the analytics service.');\n }\n\n return service;\n}\n\n/**\n *\n */\nexport function resetAnalyticsService() {\n service = null;\n}\n\n/**\n * @name AnalyticsService\n * @interface\n * @memberof module:Analytics\n * @property {function} identifyAnonymousUser\n * @property {function} identifyAuthenticatedUser\n * @property {function} sendPageEvent\n * @property {function} sendTrackEvent\n * @property {function} sendTrackingLogEvent\n */\n"],"mappings":"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"}
1
+ {"version":3,"file":"interface.js","names":["PropTypes","optionsShape","config","object","isRequired","httpClient","oneOfType","func","loggingService","shape","logError","logInfo","serviceShape","sendTrackingLogEvent","identifyAuthenticatedUser","identifyAnonymousUser","sendTrackEvent","sendPageEvent","service","configure","AnalyticsService","options","checkPropTypes","eventName","properties","userId","traits","category","name","getAnalyticsService","Error","resetAnalyticsService"],"sources":["../../src/analytics/interface.js"],"sourcesContent":["/**\n * #### Import members from **@edx/frontend-platform/analytics**\n *\n * Contains a shared interface for tracking events. Has a default implementation of\n * SegmentAnalyticsService, which supports Segment and the Tracking Log API (hosted in LMS).\n *\n * The `initialize` function performs much of the analytics configuration for you. If, however,\n * you're not using the `initialize` function, analytics can be configured via:\n *\n * ```\n * import { configure, SegmentAnalyticsService } from '@edx/frontend-platform/analytics';\n * import { getConfig } from '@edx/frontend-platform';\n * import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';\n * import { getLoggingService } from '@edx/frontend-platform/logging';\n *\n * configure(SegmentAnalyticsService, {\n * config: getConfig(),\n * loggingService: getLoggingService(),\n * httpClient: getAuthenticatedHttpClient(),\n * });\n * ```\n *\n * As shown in this example, analytics depends on the configuration document, logging, and having\n * an authenticated HTTP client.\n *\n * @module Analytics\n */\nimport PropTypes from 'prop-types';\n\nconst optionsShape = {\n config: PropTypes.object.isRequired,\n httpClient: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired,\n loggingService: PropTypes.shape({\n logError: PropTypes.func.isRequired,\n logInfo: PropTypes.func.isRequired,\n }).isRequired,\n};\n\nconst serviceShape = {\n sendTrackingLogEvent: PropTypes.func.isRequired,\n identifyAuthenticatedUser: PropTypes.func.isRequired,\n identifyAnonymousUser: PropTypes.func.isRequired,\n sendTrackEvent: PropTypes.func.isRequired,\n sendPageEvent: PropTypes.func.isRequired,\n};\n\nlet service;\n\n/**\n *\n * @param {class} AnalyticsService\n * @param {*} options\n * @returns {AnalyticsService}\n */\nexport function configure(AnalyticsService, options) {\n PropTypes.checkPropTypes(optionsShape, options, 'property', 'Analytics');\n service = new AnalyticsService(options);\n PropTypes.checkPropTypes(serviceShape, service, 'property', 'AnalyticsService');\n return service;\n}\n\n/**\n *\n * @param {*} eventName\n * @param {*} properties\n * @returns {Promise}\n */\nexport function sendTrackingLogEvent(eventName, properties) {\n return service.sendTrackingLogEvent(eventName, properties);\n}\n\n/**\n *\n *\n * @param {*} userId\n * @param {*} traits\n */\nexport function identifyAuthenticatedUser(userId, traits) {\n service.identifyAuthenticatedUser(userId, traits);\n}\n\n/**\n *\n *\n * @param {*} traits\n * @returns {Promise}\n */\nexport function identifyAnonymousUser(traits) {\n return service.identifyAnonymousUser(traits);\n}\n\n/**\n *\n *\n * @param {*} eventName\n * @param {*} properties\n */\nexport function sendTrackEvent(eventName, properties) {\n service.sendTrackEvent(eventName, properties);\n}\n\n/**\n *\n *\n * @param {*} category\n * @param {*} name\n * @param {*} properties\n */\nexport function sendPageEvent(category, name, properties) {\n service.sendPageEvent(category, name, properties);\n}\n\n/**\n *\n *\n * @returns {AnalyticsService}\n */\nexport function getAnalyticsService() {\n if (!service) {\n throw Error('You must first configure the analytics service.');\n }\n\n return service;\n}\n\n/**\n *\n */\nexport function resetAnalyticsService() {\n service = null;\n}\n\n/**\n * @name AnalyticsService\n * @interface\n * @memberof module:Analytics\n * @property {function} identifyAnonymousUser\n * @property {function} identifyAuthenticatedUser\n * @property {function} sendPageEvent\n * @property {function} sendTrackEvent\n * @property {function} sendTrackingLogEvent\n */\n"],"mappings":"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"}