@openedx/frontend-base 1.0.0-alpha.0

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 (356) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +112 -0
  3. package/config/babel/babel.config.js +28 -0
  4. package/config/config-helpers/createConfig.js +13 -0
  5. package/config/config-helpers/createLintConfig.js +16 -0
  6. package/config/config-helpers/getBaseConfig.js +12 -0
  7. package/config/defaultConfigPaths.js +35 -0
  8. package/config/eslint/base.eslint.config.js +113 -0
  9. package/config/index.js +12 -0
  10. package/config/jest/jest.config.js +30 -0
  11. package/config/tsconfig.json +32 -0
  12. package/config/types.js +25 -0
  13. package/config/webpack/common-config/all/getCodeRules.js +52 -0
  14. package/config/webpack/common-config/all/getFileLoaderRules.js +26 -0
  15. package/config/webpack/common-config/all/getIgnoreWarnings.js +14 -0
  16. package/config/webpack/common-config/all/getImageMinimizer.js +25 -0
  17. package/config/webpack/common-config/all/getStylesheetRule.js +112 -0
  18. package/config/webpack/common-config/dev/getDevServer.js +38 -0
  19. package/config/webpack/common-config/index.js +18 -0
  20. package/config/webpack/common-config/site/getHtmlWebpackPlugin.js +16 -0
  21. package/config/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.js +91 -0
  22. package/config/webpack/plugins/html-webpack-new-relic-plugin/index.js +7 -0
  23. package/config/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +3 -0
  24. package/config/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.js +108 -0
  25. package/config/webpack/plugins/paragon-webpack-plugin/index.js +7 -0
  26. package/config/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.js +64 -0
  27. package/config/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.js +53 -0
  28. package/config/webpack/plugins/paragon-webpack-plugin/utils/index.js +9 -0
  29. package/config/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.js +114 -0
  30. package/config/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.js +146 -0
  31. package/config/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.js +126 -0
  32. package/config/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.js +57 -0
  33. package/config/webpack/types.js +2 -0
  34. package/config/webpack/utils/getLocalAliases.js +65 -0
  35. package/config/webpack/utils/getPublicPath.js +6 -0
  36. package/config/webpack/utils/getResolvedSiteConfigPath.js +32 -0
  37. package/config/webpack/utils/paragonUtils.js +138 -0
  38. package/config/webpack/webpack.config.build.js +80 -0
  39. package/config/webpack/webpack.config.dev.js +76 -0
  40. package/config/webpack/webpack.config.dev.shell.js +110 -0
  41. package/eslint.config.js +18 -0
  42. package/frontend-base.d.ts +8 -0
  43. package/index.ts +7 -0
  44. package/jest.config.js +7 -0
  45. package/openedx-frontend-base.tgz +0 -0
  46. package/package.json +149 -0
  47. package/runtime/analytics/MockAnalyticsService.js +71 -0
  48. package/runtime/analytics/SegmentAnalyticsService.js +243 -0
  49. package/runtime/analytics/index.ts +12 -0
  50. package/runtime/analytics/interface.js +145 -0
  51. package/runtime/auth/AxiosCsrfTokenService.js +60 -0
  52. package/runtime/auth/AxiosJwtAuthService.js +363 -0
  53. package/runtime/auth/AxiosJwtTokenService.js +134 -0
  54. package/runtime/auth/LocalForageCache.js +76 -0
  55. package/runtime/auth/MockAuthService.js +278 -0
  56. package/runtime/auth/index.ts +19 -0
  57. package/runtime/auth/interceptors/createCsrfTokenProviderInterceptor.js +36 -0
  58. package/runtime/auth/interceptors/createJwtTokenProviderInterceptor.js +37 -0
  59. package/runtime/auth/interceptors/createProcessAxiosRequestErrorInterceptor.js +20 -0
  60. package/runtime/auth/interceptors/createRetryInterceptor.js +74 -0
  61. package/runtime/auth/interface.js +309 -0
  62. package/runtime/auth/utils.js +105 -0
  63. package/runtime/babel.config.js +3 -0
  64. package/runtime/config/index.ts +295 -0
  65. package/runtime/constants.ts +68 -0
  66. package/runtime/i18n/index.js +118 -0
  67. package/runtime/i18n/injectIntlWithShim.jsx +48 -0
  68. package/runtime/i18n/lib.ts +272 -0
  69. package/runtime/index.ts +134 -0
  70. package/runtime/initialize.js +352 -0
  71. package/runtime/jest.config.js +32 -0
  72. package/runtime/logging/MockLoggingService.js +31 -0
  73. package/runtime/logging/NewRelicLoggingService.js +184 -0
  74. package/runtime/logging/index.ts +9 -0
  75. package/runtime/logging/interface.js +109 -0
  76. package/runtime/logging/types.ts +4 -0
  77. package/runtime/react/AuthenticatedPageRoute.jsx +43 -0
  78. package/runtime/react/CombinedAppProvider.tsx +46 -0
  79. package/runtime/react/CurrentAppContext.tsx +25 -0
  80. package/runtime/react/CurrentAppProvider.tsx +46 -0
  81. package/runtime/react/Divider.tsx +5 -0
  82. package/runtime/react/ErrorBoundary.jsx +47 -0
  83. package/runtime/react/ErrorPage.jsx +72 -0
  84. package/runtime/react/LoginRedirect.jsx +16 -0
  85. package/runtime/react/PageWrap.jsx +24 -0
  86. package/runtime/react/SiteContext.tsx +32 -0
  87. package/runtime/react/SiteProvider.tsx +78 -0
  88. package/runtime/react/hooks.ts +106 -0
  89. package/runtime/react/index.ts +19 -0
  90. package/runtime/routing/index.ts +1 -0
  91. package/runtime/routing/utils.ts +34 -0
  92. package/runtime/scripts/GoogleAnalyticsLoader.ts +59 -0
  93. package/runtime/scripts/index.ts +1 -0
  94. package/runtime/setupTest.js +49 -0
  95. package/runtime/slots/Slot.tsx +32 -0
  96. package/runtime/slots/SlotContext.tsx +8 -0
  97. package/runtime/slots/hooks.ts +35 -0
  98. package/runtime/slots/index.ts +7 -0
  99. package/runtime/slots/layout/DefaultSlotLayout.tsx +9 -0
  100. package/runtime/slots/layout/hooks.ts +65 -0
  101. package/runtime/slots/layout/index.ts +5 -0
  102. package/runtime/slots/layout/types.ts +45 -0
  103. package/runtime/slots/layout/utils.ts +14 -0
  104. package/runtime/slots/types.ts +23 -0
  105. package/runtime/slots/utils.ts +59 -0
  106. package/runtime/slots/widget/WidgetContext.tsx +9 -0
  107. package/runtime/slots/widget/WidgetProvider.tsx +30 -0
  108. package/runtime/slots/widget/hooks.ts +105 -0
  109. package/runtime/slots/widget/iframe/IFrameContentWrapper.messages.tsx +16 -0
  110. package/runtime/slots/widget/iframe/IFrameContentWrapper.tsx +84 -0
  111. package/runtime/slots/widget/iframe/IFrameWidget.tsx +59 -0
  112. package/runtime/slots/widget/iframe/constants.ts +19 -0
  113. package/runtime/slots/widget/iframe/hooks.ts +179 -0
  114. package/runtime/slots/widget/iframe/index.ts +6 -0
  115. package/runtime/slots/widget/iframe/types.ts +7 -0
  116. package/runtime/slots/widget/index.ts +6 -0
  117. package/runtime/slots/widget/types.ts +134 -0
  118. package/runtime/slots/widget/utils.tsx +201 -0
  119. package/runtime/subscriptions.ts +60 -0
  120. package/runtime/testing/index.ts +9 -0
  121. package/runtime/testing/initializeMockApp.ts +81 -0
  122. package/runtime/testing/mockMessages.ts +23 -0
  123. package/runtime/utils.js +178 -0
  124. package/shell/DefaultLayout.tsx +18 -0
  125. package/shell/DefaultMain.tsx +7 -0
  126. package/shell/Logo.tsx +28 -0
  127. package/shell/Shell.messages.ts +61 -0
  128. package/shell/Shell.tsx +18 -0
  129. package/shell/app.scss +149 -0
  130. package/shell/app.ts +24 -0
  131. package/shell/babel.config.js +3 -0
  132. package/shell/dev/devFooter/app.tsx +43 -0
  133. package/shell/dev/devFooter/index.ts +1 -0
  134. package/shell/dev/devHeader/BarContext.tsx +13 -0
  135. package/shell/dev/devHeader/BarLink.tsx +16 -0
  136. package/shell/dev/devHeader/BarProvider.tsx +25 -0
  137. package/shell/dev/devHeader/CoursesLink.tsx +16 -0
  138. package/shell/dev/devHeader/FooContext.tsx +13 -0
  139. package/shell/dev/devHeader/FooLink.tsx +16 -0
  140. package/shell/dev/devHeader/FooProvider.tsx +25 -0
  141. package/shell/dev/devHeader/app.tsx +53 -0
  142. package/shell/dev/devHeader/index.ts +1 -0
  143. package/shell/dev/devHeader/providers.tsx +11 -0
  144. package/shell/dev/devHome/HomePage.tsx +28 -0
  145. package/shell/dev/devHome/app.ts +18 -0
  146. package/shell/dev/devHome/i18n/index.ts +27 -0
  147. package/shell/dev/devHome/index.ts +1 -0
  148. package/shell/dev/devHome/messages.ts +11 -0
  149. package/shell/dev/devUser/app.tsx +24 -0
  150. package/shell/dev/devUser/index.ts +1 -0
  151. package/shell/dev/index.ts +5 -0
  152. package/shell/dev/slotShowcase/HorizontalSlotLayout.tsx +11 -0
  153. package/shell/dev/slotShowcase/LayoutWithOptions.tsx +17 -0
  154. package/shell/dev/slotShowcase/SlotShowcasePage.tsx +66 -0
  155. package/shell/dev/slotShowcase/WidgetWithOptions.tsx +11 -0
  156. package/shell/dev/slotShowcase/app.tsx +373 -0
  157. package/shell/dev/slotShowcase/index.ts +1 -0
  158. package/shell/footer/CenterLinks.tsx +11 -0
  159. package/shell/footer/CopyrightNotice.tsx +36 -0
  160. package/shell/footer/Footer.tsx +34 -0
  161. package/shell/footer/LabeledLinkColumn.tsx +19 -0
  162. package/shell/footer/LanguageMenu.tsx +35 -0
  163. package/shell/footer/LanguageMenuItem.tsx +23 -0
  164. package/shell/footer/LeftLinks.tsx +11 -0
  165. package/shell/footer/LegalNotices.tsx +17 -0
  166. package/shell/footer/PoweredBy.tsx +17 -0
  167. package/shell/footer/RevealLinks.tsx +43 -0
  168. package/shell/footer/RightLinks.tsx +11 -0
  169. package/shell/footer/app.tsx +73 -0
  170. package/shell/footer/data/api.ts +48 -0
  171. package/shell/footer/index.ts +2 -0
  172. package/shell/header/AuthenticatedMenu.tsx +32 -0
  173. package/shell/header/Header.tsx +17 -0
  174. package/shell/header/anonymous-menu/AnonymousMenu.tsx +14 -0
  175. package/shell/header/anonymous-menu/LoginButton.tsx +14 -0
  176. package/shell/header/anonymous-menu/RegisterButton.tsx +15 -0
  177. package/shell/header/app.tsx +142 -0
  178. package/shell/header/desktop/DesktopLayout.tsx +22 -0
  179. package/shell/header/desktop/PrimaryNavLinks.tsx +10 -0
  180. package/shell/header/desktop/SecondaryNavLinks.tsx +10 -0
  181. package/shell/header/index.ts +2 -0
  182. package/shell/header/mobile/MobileLayout.tsx +47 -0
  183. package/shell/header/mobile/MobileNavLinks.tsx +10 -0
  184. package/shell/i18n/index.ts +25 -0
  185. package/shell/index.ts +7 -0
  186. package/shell/jest.config.js +30 -0
  187. package/shell/menus/LinkMenuItem.tsx +64 -0
  188. package/shell/menus/NavDropdownMenuSlot.tsx +29 -0
  189. package/shell/menus/ProfileLinkMenuItem.tsx +33 -0
  190. package/shell/menus/data/utils.ts +19 -0
  191. package/shell/public/index.html +10 -0
  192. package/shell/router/createRouter.ts +17 -0
  193. package/shell/router/getAppRoutes.ts +21 -0
  194. package/shell/setupTest.js +48 -0
  195. package/shell/site.config.dev.tsx +49 -0
  196. package/shell/site.tsx +41 -0
  197. package/test-site/app.d.ts +15 -0
  198. package/test-site/dist/176.436443549ebb858db483.js +2 -0
  199. package/test-site/dist/176.436443549ebb858db483.js.map +1 -0
  200. package/test-site/dist/362.536eff787d2380fe246c.js +2 -0
  201. package/test-site/dist/362.536eff787d2380fe246c.js.map +1 -0
  202. package/test-site/dist/653.486966b108d224551296.js +2 -0
  203. package/test-site/dist/653.486966b108d224551296.js.map +1 -0
  204. package/test-site/dist/74e025d3fe9a7b7f8503054e2563b353.jpg +0 -0
  205. package/test-site/dist/806.323cf6496ad0a7fe73a7.js +3 -0
  206. package/test-site/dist/806.323cf6496ad0a7fe73a7.js.LICENSE.txt +106 -0
  207. package/test-site/dist/806.323cf6496ad0a7fe73a7.js.map +1 -0
  208. package/test-site/dist/95ec738c0b7faac5b5c9126794446bbd.svg +4 -0
  209. package/test-site/dist/app.612058b36c74787759ac.css +61 -0
  210. package/test-site/dist/app.612058b36c74787759ac.css.map +1 -0
  211. package/test-site/dist/app.612058b36c74787759ac.js +2 -0
  212. package/test-site/dist/app.612058b36c74787759ac.js.map +1 -0
  213. package/test-site/dist/cb28cdb1468c915e27e5cec9af64f22f.svg +1 -0
  214. package/test-site/dist/index.html +1 -0
  215. package/test-site/dist/report.html +39 -0
  216. package/test-site/dist/runtime.c7aeaf7b967496cb076f.js +2 -0
  217. package/test-site/dist/runtime.c7aeaf7b967496cb076f.js.map +1 -0
  218. package/test-site/eslint.config.js +12 -0
  219. package/test-site/package-lock.json +19226 -0
  220. package/test-site/package.json +29 -0
  221. package/test-site/public/index.html +10 -0
  222. package/test-site/site.config.build.tsx +27 -0
  223. package/test-site/site.config.dev.tsx +27 -0
  224. package/test-site/src/authenticated-page/AuthenticatedPage.tsx +18 -0
  225. package/test-site/src/authenticated-page/i18n/index.ts +27 -0
  226. package/test-site/src/authenticated-page/index.tsx +28 -0
  227. package/test-site/src/example-page/ExamplePage.tsx +79 -0
  228. package/test-site/src/example-page/Image.tsx +11 -0
  229. package/test-site/src/example-page/ParagonPreview.jsx +66 -0
  230. package/test-site/src/example-page/apple.jpg +0 -0
  231. package/test-site/src/example-page/apple.svg +1 -0
  232. package/test-site/src/example-page/index.ts +16 -0
  233. package/test-site/src/i18n/README.md +3 -0
  234. package/test-site/src/i18n/messages/frontend-app-sample/ar.json +4 -0
  235. package/test-site/src/i18n/messages/frontend-app-sample/eo.json +1 -0
  236. package/test-site/src/i18n/messages/frontend-app-sample/es_419.json +4 -0
  237. package/test-site/src/i18n/messages/frontend-component-emptylangs/ar.json +1 -0
  238. package/test-site/src/i18n/messages/frontend-component-singlelang/ar.json +3 -0
  239. package/test-site/src/iframe-widget/IframeWidget.tsx +14 -0
  240. package/test-site/src/iframe-widget/index.ts +16 -0
  241. package/test-site/src/index.tsx +3 -0
  242. package/test-site/src/messages.js +11 -0
  243. package/test-site/src/site.scss +11 -0
  244. package/test-site/tsconfig.json +14 -0
  245. package/tools/babel/babel.config.js +27 -0
  246. package/tools/babel.config.js +3 -0
  247. package/tools/cli/README.md +29 -0
  248. package/tools/cli/commands/pack.ts +9 -0
  249. package/tools/cli/commands/release.ts +27 -0
  250. package/tools/cli/commands/serve.ts +43 -0
  251. package/tools/cli/intl-imports.ts +274 -0
  252. package/tools/cli/openedx.ts +101 -0
  253. package/tools/cli/transifex-utils.ts +75 -0
  254. package/tools/cli/utils/ensureConfigFilenameOption.ts +40 -0
  255. package/tools/cli/utils/formatter.ts +10 -0
  256. package/tools/cli/utils/getResolvedConfigPath.ts +23 -0
  257. package/tools/cli/utils/prettyPrintTitle.ts +15 -0
  258. package/tools/cli/utils/printUsage.ts +53 -0
  259. package/tools/config-helpers/createConfig.ts +8 -0
  260. package/tools/config-helpers/createLintConfig.ts +14 -0
  261. package/tools/config-helpers/getBaseConfig.ts +11 -0
  262. package/tools/defaultConfigPaths.ts +30 -0
  263. package/tools/dist/babel/babel.config.js +28 -0
  264. package/tools/dist/cli/commands/pack.js +14 -0
  265. package/tools/dist/cli/commands/release.js +28 -0
  266. package/tools/dist/cli/commands/serve.js +44 -0
  267. package/tools/dist/cli/intl-imports.js +233 -0
  268. package/tools/dist/cli/openedx.js +100 -0
  269. package/tools/dist/cli/transifex-utils.js +68 -0
  270. package/tools/dist/cli/utils/ensureConfigFilenameOption.js +42 -0
  271. package/tools/dist/cli/utils/formatter.js +10 -0
  272. package/tools/dist/cli/utils/getResolvedConfigPath.js +28 -0
  273. package/tools/dist/cli/utils/prettyPrintTitle.js +17 -0
  274. package/tools/dist/cli/utils/printUsage.js +48 -0
  275. package/tools/dist/config-helpers/createConfig.js +13 -0
  276. package/tools/dist/config-helpers/createLintConfig.js +16 -0
  277. package/tools/dist/config-helpers/getBaseConfig.js +12 -0
  278. package/tools/dist/defaultConfigPaths.js +35 -0
  279. package/tools/dist/eslint/base.eslint.config.js +113 -0
  280. package/tools/dist/eslint.config.js +11 -0
  281. package/tools/dist/index.js +12 -0
  282. package/tools/dist/jest/jest.config.js +30 -0
  283. package/tools/dist/jest.config.js +20 -0
  284. package/tools/dist/types.js +25 -0
  285. package/tools/dist/typescript/tsconfig.json +32 -0
  286. package/tools/dist/webpack/common-config/all/getCodeRules.js +52 -0
  287. package/tools/dist/webpack/common-config/all/getFileLoaderRules.js +26 -0
  288. package/tools/dist/webpack/common-config/all/getIgnoreWarnings.js +14 -0
  289. package/tools/dist/webpack/common-config/all/getImageMinimizer.js +25 -0
  290. package/tools/dist/webpack/common-config/all/getStylesheetRule.js +112 -0
  291. package/tools/dist/webpack/common-config/dev/getDevServer.js +38 -0
  292. package/tools/dist/webpack/common-config/index.js +18 -0
  293. package/tools/dist/webpack/common-config/site/getHtmlWebpackPlugin.js +16 -0
  294. package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.js +91 -0
  295. package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/index.js +7 -0
  296. package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +3 -0
  297. package/tools/dist/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.js +108 -0
  298. package/tools/dist/webpack/plugins/paragon-webpack-plugin/index.js +7 -0
  299. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.js +64 -0
  300. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.js +53 -0
  301. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/index.js +9 -0
  302. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.js +114 -0
  303. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.js +146 -0
  304. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.js +126 -0
  305. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.js +57 -0
  306. package/tools/dist/webpack/types.js +2 -0
  307. package/tools/dist/webpack/utils/getLocalAliases.js +65 -0
  308. package/tools/dist/webpack/utils/getPublicPath.js +6 -0
  309. package/tools/dist/webpack/utils/getResolvedSiteConfigPath.js +32 -0
  310. package/tools/dist/webpack/utils/paragonUtils.js +138 -0
  311. package/tools/dist/webpack/webpack.config.build.js +80 -0
  312. package/tools/dist/webpack/webpack.config.dev.js +76 -0
  313. package/tools/dist/webpack/webpack.config.dev.shell.js +110 -0
  314. package/tools/eslint/base.eslint.config.js +124 -0
  315. package/tools/eslint/modules.d.ts +5 -0
  316. package/tools/eslint.config.js +15 -0
  317. package/tools/index.ts +3 -0
  318. package/tools/jest/jest.config.js +30 -0
  319. package/tools/jest.config.js +19 -0
  320. package/tools/tsconfig.json +24 -0
  321. package/tools/types.ts +21 -0
  322. package/tools/typescript/tsconfig.json +32 -0
  323. package/tools/webpack/common-config/README.md +15 -0
  324. package/tools/webpack/common-config/all/getCodeRules.ts +51 -0
  325. package/tools/webpack/common-config/all/getFileLoaderRules.ts +23 -0
  326. package/tools/webpack/common-config/all/getIgnoreWarnings.ts +13 -0
  327. package/tools/webpack/common-config/all/getImageMinimizer.ts +26 -0
  328. package/tools/webpack/common-config/all/getStylesheetRule.ts +111 -0
  329. package/tools/webpack/common-config/dev/getDevServer.ts +35 -0
  330. package/tools/webpack/common-config/index.ts +6 -0
  331. package/tools/webpack/common-config/site/getHtmlWebpackPlugin.ts +11 -0
  332. package/tools/webpack/modules.d.ts +6 -0
  333. package/tools/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.ts +102 -0
  334. package/tools/webpack/plugins/html-webpack-new-relic-plugin/LICENSE +21 -0
  335. package/tools/webpack/plugins/html-webpack-new-relic-plugin/README.md +7 -0
  336. package/tools/webpack/plugins/html-webpack-new-relic-plugin/index.js +3 -0
  337. package/tools/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +1 -0
  338. package/tools/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.ts +134 -0
  339. package/tools/webpack/plugins/paragon-webpack-plugin/index.ts +3 -0
  340. package/tools/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.ts +71 -0
  341. package/tools/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.ts +72 -0
  342. package/tools/webpack/plugins/paragon-webpack-plugin/utils/index.ts +6 -0
  343. package/tools/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.ts +131 -0
  344. package/tools/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.ts +144 -0
  345. package/tools/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.ts +106 -0
  346. package/tools/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.ts +54 -0
  347. package/tools/webpack/types.ts +69 -0
  348. package/tools/webpack/utils/getLocalAliases.ts +65 -0
  349. package/tools/webpack/utils/getPublicPath.ts +3 -0
  350. package/tools/webpack/utils/getResolvedSiteConfigPath.ts +28 -0
  351. package/tools/webpack/utils/paragonUtils.ts +152 -0
  352. package/tools/webpack/webpack.config.build.ts +93 -0
  353. package/tools/webpack/webpack.config.dev.shell.ts +122 -0
  354. package/tools/webpack/webpack.config.dev.ts +90 -0
  355. package/tsconfig.json +23 -0
  356. package/types.ts +99 -0
@@ -0,0 +1,352 @@
1
+ /**
2
+ * #### Import members from **@openedx/frontend-base**
3
+ *
4
+ * The initialization module provides a function for managing an application's initialization
5
+ * lifecycle. It also provides constants and default handler implementations.
6
+ *
7
+ * ```
8
+ * import {
9
+ * initialize,
10
+ * SITE_INIT_ERROR,
11
+ * SITE_READY,
12
+ * subscribe,
13
+ * SiteProvider,
14
+ * ErrorPage,
15
+ * PageWrap
16
+ * } from '@openedx/frontend-base';
17
+ * import React from 'react';
18
+ * import ReactDOM from 'react-dom';
19
+ * import { Routes, Route } from 'react-router-dom';
20
+ *
21
+ * subscribe(SITE_READY, () => {
22
+ * ReactDOM.render(
23
+ * <SiteProvider>
24
+ * <Header />
25
+ * <main>
26
+ * <Routes>
27
+ * <Route path="/" element={<PageWrap><PaymentPage /></PageWrap>} />
28
+ * </Routes>
29
+ * </main>
30
+ * <Footer />
31
+ * </SiteProvider>,
32
+ * document.getElementById('root'),
33
+ * );
34
+ * });
35
+ *
36
+ * subscribe(SITE_INIT_ERROR, (error) => {
37
+ * ReactDOM.render(<ErrorPage message={error.message} />, document.getElementById('root'));
38
+ * });
39
+ *
40
+ * initialize({
41
+ * messages: [appMessages],
42
+ * requireAuthenticatedUser: true,
43
+ * hydrateAuthenticatedUser: true,
44
+ * });
45
+
46
+ ```
47
+ * @module Initialization
48
+ */
49
+
50
+ /*
51
+ This 'site.config' package is a special 'magic' alias in our webpack configuration in the `config`
52
+ folder. It points at an `site.config.tsx` file in the root of a site's repository.
53
+ */
54
+ import siteConfig from 'site.config';
55
+ import {
56
+ configureAnalytics,
57
+ identifyAnonymousUser,
58
+ identifyAuthenticatedUser,
59
+ SegmentAnalyticsService,
60
+ } from './analytics';
61
+ import {
62
+ AxiosJwtAuthService,
63
+ configureAuth,
64
+ ensureAuthenticatedUser,
65
+ fetchAuthenticatedUser,
66
+ getAuthenticatedHttpClient,
67
+ getAuthenticatedUser,
68
+ hydrateAuthenticatedUser,
69
+ } from './auth';
70
+ import configureCache from './auth/LocalForageCache';
71
+ import {
72
+ getSiteConfig, mergeSiteConfig,
73
+ } from './config';
74
+ import {
75
+ SITE_ANALYTICS_INITIALIZED,
76
+ SITE_AUTH_INITIALIZED,
77
+ SITE_CONFIG_INITIALIZED,
78
+ SITE_I18N_INITIALIZED,
79
+ SITE_INIT_ERROR,
80
+ SITE_LOGGING_INITIALIZED,
81
+ SITE_PUBSUB_INITIALIZED,
82
+ SITE_READY,
83
+ } from './constants';
84
+ import { configureI18n } from './i18n';
85
+ import {
86
+ configureLogging,
87
+ getLoggingService,
88
+ logError,
89
+ NewRelicLoggingService,
90
+ } from './logging';
91
+ import { GoogleAnalyticsLoader } from './scripts';
92
+ import { publish } from './subscriptions';
93
+
94
+ /**
95
+ * If set in configuration, a basename will be prepended to all relative routes under BrowserRouter.
96
+ *
97
+ * Unlike webpack's publicPath, the basename cannot be auto-discovered, so when publicPath is set
98
+ * (or when it's set to 'auto' and the site is being served from a path other than '/') this
99
+ * needs to be configured.
100
+ */
101
+ export const getBasename = () => getSiteConfig().basename;
102
+
103
+ /**
104
+ * The default handler for the initialization lifecycle's `initError` phase. Logs the error to the
105
+ * LoggingService using `logError`
106
+ *
107
+ * @see {@link module:frontend-base~logError}
108
+ * @param {*} error
109
+ */
110
+ export async function initError(error) {
111
+ logError(error);
112
+ }
113
+
114
+ /**
115
+ * The default handler for the initialization lifecycle's `auth` phase.
116
+ *
117
+ * The handler has several responsibilities:
118
+ * - Determining the user's authentication state (authenticated or anonymous)
119
+ * - Optionally redirecting to login if the application requires an authenticated user.
120
+ * - Optionally loading additional user information via the application's user account data
121
+ * endpoint.
122
+ *
123
+ * @param {boolean} requireUser Whether or not we should redirect to login if a user is not
124
+ * authenticated.
125
+ * @param {boolean} hydrateUser Whether or not we should fetch additional user account data.
126
+ */
127
+ export async function auth(requireUser, hydrateUser) {
128
+ if (requireUser) {
129
+ await ensureAuthenticatedUser(globalThis.location.href);
130
+ } else {
131
+ await fetchAuthenticatedUser();
132
+ }
133
+
134
+ if (hydrateUser && getAuthenticatedUser() !== null) {
135
+ // We intentionally do not await the promise returned by hydrateAuthenticatedUser. All the
136
+ // critical data is returned as part of fetch/ensureAuthenticatedUser above, and anything else
137
+ // is a nice-to-have for application code.
138
+ hydrateAuthenticatedUser();
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Set or overrides configuration via an site.config.tsx file in the consuming application.
144
+ * This site.config.tsx is loaded at runtime and must export one of two things:
145
+ *
146
+ * - An object which will be merged into the application config via `mergeSiteConfig`.
147
+ * - A function which returns an object which will be merged into the application config via
148
+ * `mergeSiteConfig`. This function can return a promise.
149
+ */
150
+ async function fileConfig() {
151
+ let config = {};
152
+ if (typeof siteConfig === 'function') {
153
+ config = await siteConfig();
154
+ } else {
155
+ config = siteConfig;
156
+ }
157
+
158
+ mergeSiteConfig(config);
159
+ }
160
+
161
+ /*
162
+ * Set or overrides configuration through an API.
163
+ * This method allows runtime configuration.
164
+ * Set a basic configuration when an error happen and allow initError and display the ErrorPage.
165
+ */
166
+ async function runtimeConfig() {
167
+ try {
168
+ const { mfeConfigApiUrl, siteId } = getSiteConfig();
169
+
170
+ if (mfeConfigApiUrl) {
171
+ const apiConfig = { headers: { accept: 'application/json' } };
172
+ const apiService = await configureCache();
173
+
174
+ const params = new URLSearchParams();
175
+ params.append('mfe', siteId);
176
+ const url = `${mfeConfigApiUrl}?${params.toString()}`;
177
+
178
+ const { data } = await apiService.get(url, apiConfig);
179
+ mergeSiteConfig(data);
180
+ }
181
+ } catch (error) {
182
+ console.error('Error with config API', error.message);
183
+ }
184
+ }
185
+
186
+ export function loadExternalScripts(externalScripts, data) {
187
+ externalScripts.forEach(ExternalScript => {
188
+ const script = new ExternalScript(data);
189
+ script.loadScript();
190
+ });
191
+ }
192
+
193
+ /**
194
+ * The default handler for the initialization lifecycle's `analytics` phase.
195
+ *
196
+ * The handler is responsible for identifying authenticated and anonymous users with the analytics
197
+ * service. This is a pre-requisite for sending analytics events, thus, we do it during the
198
+ * initialization sequence so that analytics is ready once the application's UI code starts to load.
199
+ *
200
+ */
201
+ export async function analytics() {
202
+ const authenticatedUser = getAuthenticatedUser();
203
+ if (authenticatedUser?.userId) {
204
+ identifyAuthenticatedUser(authenticatedUser.userId);
205
+ } else {
206
+ await identifyAnonymousUser();
207
+ }
208
+ }
209
+
210
+ function applyOverrideHandlers(overrides) {
211
+ const noOp = async () => { };
212
+ return {
213
+ pubSub: noOp,
214
+ config: noOp,
215
+ logging: noOp,
216
+ auth,
217
+ analytics,
218
+ i18n: noOp,
219
+ ready: noOp,
220
+ initError,
221
+ ...overrides, // This will override any same-keyed handlers from above.
222
+ };
223
+ }
224
+
225
+ /**
226
+ * Invokes the application initialization sequence.
227
+ *
228
+ * The sequence proceeds through a number of lifecycle phases, during which pertinent services are
229
+ * configured.
230
+ *
231
+ * Using the `handlers` option, lifecycle phase handlers can be overridden to perform custom
232
+ * functionality. Note that while these override handlers _do_ replace the default handler
233
+ * functionality for analytics, auth, and initError (the other phases have no default
234
+ * functionality), they do _not_ override the configuration of the actual services that those
235
+ * handlers leverage.
236
+ *
237
+ * Some services can be overridden via the loggingService and analyticsService options. The other
238
+ * services (auth and i18n) cannot currently be overridden.
239
+ *
240
+ * The following lifecycle phases exist:
241
+ *
242
+ * - pubSub: A no-op by default.
243
+ * - config: A no-op by default.
244
+ * - logging: A no-op by default.
245
+ * - auth: Uses the 'auth' handler defined above.
246
+ * - analytics: Uses the 'analytics' handler defined above.
247
+ * - i18n: A no-op by default.
248
+ * - ready: A no-op by default.
249
+ * - initError: Uses the 'initError' handler defined above.
250
+ *
251
+ * @param {Object} [options]
252
+ * @param {*} [options.loggingService=NewRelicLoggingService] The `LoggingService` implementation
253
+ * to use.
254
+ * @param {*} [options.analyticsService=SegmentAnalyticsService] The `AnalyticsService`
255
+ * implementation to use.
256
+ * @param {*} [options.authMiddleware=[]] An array of middleware to apply to http clients in the auth service.
257
+ * @param {*} [options.externalScripts=[GoogleAnalyticsLoader]] An array of externalScripts.
258
+ * By default added GoogleAnalyticsLoader.
259
+ * @param {*} [options.requireAuthenticatedUser=false] If true, turns on automatic login
260
+ * redirection for unauthenticated users. Defaults to false, meaning that by default the
261
+ * application will allow anonymous/unauthenticated sessions.
262
+ * @param {*} [options.hydrateAuthenticatedUser=false] If true, makes an API call to the user
263
+ * account endpoint (`${App.config.lmsBaseUrl}/api/user/v1/accounts/${username}`) to fetch
264
+ * detailed account information for the authenticated user. This data is merged into the return
265
+ * value of `getAuthenticatedUser`, overriding any duplicate keys that already exist. Defaults to
266
+ * false, meaning that no additional account information will be loaded.
267
+ * @param {*} [options.messages] A i18n-compatible messages object, or an array of such objects. If
268
+ * an array is provided, duplicate keys are resolved with the last-one-in winning.
269
+ * @param {*} [options.handlers={}] An optional object of handlers which can be used to replace the
270
+ * default behavior of any part of the startup sequence. It can also be used to add additional
271
+ * initialization behavior before or after the rest of the sequence.
272
+ */
273
+ export async function initialize({
274
+ loggingService = NewRelicLoggingService,
275
+ analyticsService = SegmentAnalyticsService,
276
+ authService = AxiosJwtAuthService,
277
+ authMiddleware = [],
278
+ externalScripts = [GoogleAnalyticsLoader],
279
+ requireAuthenticatedUser: requireUser = false,
280
+ hydrateAuthenticatedUser: hydrateUser = false,
281
+ messages,
282
+ handlers: overrideHandlers = {},
283
+ }) {
284
+ const handlers = applyOverrideHandlers(overrideHandlers);
285
+ try {
286
+ // Pub/Sub
287
+ await handlers.pubSub();
288
+ publish(SITE_PUBSUB_INITIALIZED);
289
+
290
+ // Configuration
291
+ await fileConfig();
292
+ await handlers.config();
293
+ await runtimeConfig();
294
+ publish(SITE_CONFIG_INITIALIZED);
295
+
296
+ loadExternalScripts(externalScripts, {
297
+ config: getSiteConfig(),
298
+ });
299
+
300
+ // This allows us to replace the implementations of the logging, analytics, and auth services
301
+ // based on keys in the SiteConfig. The JavaScript File Configuration method is the only
302
+ // one capable of supplying an alternate implementation since it can import other modules.
303
+ // If a service wasn't supplied we fall back to the default parameters on the initialize
304
+ // function signature.
305
+ const loggingServiceImpl = getSiteConfig().loggingService ?? loggingService;
306
+ const analyticsServiceImpl = getSiteConfig().analyticsService ?? analyticsService;
307
+ const authServiceImpl = getSiteConfig().authService ?? authService;
308
+
309
+ // Logging
310
+ configureLogging(loggingServiceImpl, {
311
+ config: getSiteConfig(),
312
+ });
313
+ await handlers.logging();
314
+ publish(SITE_LOGGING_INITIALIZED);
315
+
316
+ // Internationalization
317
+ configureI18n({
318
+ messages,
319
+ });
320
+ await handlers.i18n();
321
+ publish(SITE_I18N_INITIALIZED);
322
+
323
+ // Authentication
324
+ configureAuth(authServiceImpl, {
325
+ loggingService: getLoggingService(),
326
+ config: getSiteConfig(),
327
+ middleware: authMiddleware,
328
+ });
329
+
330
+ await handlers.auth(requireUser, hydrateUser);
331
+ publish(SITE_AUTH_INITIALIZED);
332
+
333
+ // Analytics
334
+ configureAnalytics(analyticsServiceImpl, {
335
+ config: getSiteConfig(),
336
+ loggingService: getLoggingService(),
337
+ httpClient: getAuthenticatedHttpClient(),
338
+ });
339
+ await handlers.analytics();
340
+ publish(SITE_ANALYTICS_INITIALIZED);
341
+
342
+ // Application Ready
343
+ await handlers.ready();
344
+ publish(SITE_READY);
345
+ } catch (error) {
346
+ if (!error.isRedirecting) {
347
+ // Initialization Error
348
+ await handlers.initError(error);
349
+ publish(SITE_INIT_ERROR, error);
350
+ }
351
+ }
352
+ }
@@ -0,0 +1,32 @@
1
+ module.exports = {
2
+ setupFilesAfterEnv: [
3
+ '<rootDir>/setupTest.js',
4
+ ],
5
+ moduleNameMapper: {
6
+ '\\.svg$': '<rootDir>/__mocks__/svg.js',
7
+ '\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir/__mocks__/file.js',
8
+ '\\.(css|scss)$': require.resolve('identity-obj-proxy'),
9
+ 'site.config': '<rootDir>/site.config.test.tsx',
10
+ },
11
+ testEnvironment: 'jsdom',
12
+ testEnvironmentOptions: {
13
+ url: 'http://localhost/',
14
+ },
15
+ collectCoverageFrom: [
16
+ '<rootDir>/**/*.{js,jsx,ts,tsx}',
17
+ ],
18
+ coveragePathIgnorePatterns: [
19
+ '<rootDir>/setupTest.js',
20
+ ],
21
+ transformIgnorePatterns: [
22
+ '/node_modules/(?!(@openedx|@edx)/)',
23
+ ],
24
+ modulePathIgnorePatterns: [
25
+ '/dist/',
26
+ ],
27
+ testPathIgnorePatterns: [
28
+ '/site.config.test.tsx',
29
+ '/node_modules/',
30
+ '/dist/',
31
+ ],
32
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The MockLoggingService implements both logInfo and logError as jest mock functions via
3
+ * jest.fn(). It has no other functionality.
4
+ *
5
+ * @implements {LoggingService}
6
+ * @memberof module:Logging
7
+ */
8
+ class MockLoggingService {
9
+ /**
10
+ * Implemented as a jest.fn()
11
+ *
12
+ * @memberof MockLoggingService
13
+ */
14
+ logInfo = jest.fn();
15
+
16
+ /**
17
+ * Implemented as a jest.fn()
18
+ *
19
+ * @memberof MockLoggingService
20
+ */
21
+ logError = jest.fn();
22
+
23
+ /**
24
+ * Implemented as a jest.fn()
25
+ *
26
+ * @memberof MockLoggingService
27
+ */
28
+ setCustomAttribute = jest.fn();
29
+ }
30
+
31
+ export default MockLoggingService;
@@ -0,0 +1,184 @@
1
+ import { EnvironmentTypes } from '../../types';
2
+ import { getSiteConfig } from '../config';
3
+
4
+ /**
5
+ * NewRelic will not log an error if it is too long.
6
+ *
7
+ * @ignore
8
+ */
9
+ export const MAX_ERROR_LENGTH = 4000;
10
+
11
+ function fixErrorLength(error) {
12
+ if (error.message && error.message.length > MAX_ERROR_LENGTH) {
13
+ const processedError = Object.create(error);
14
+ processedError.message = processedError.message.substring(0, MAX_ERROR_LENGTH);
15
+ return processedError;
16
+ }
17
+ if (typeof error === 'string' && error.length > MAX_ERROR_LENGTH) {
18
+ return error.substring(0, MAX_ERROR_LENGTH);
19
+ }
20
+ return error;
21
+ }
22
+
23
+ /* Constants used as New Relic page action names. */
24
+ const pageActionNameInfo = 'INFO';
25
+ const pageActionNameIgnoredError = 'IGNORED_ERROR';
26
+
27
+ function sendPageAction(actionName, message, customAttributes) {
28
+ if (getSiteConfig().environment === EnvironmentTypes.DEVELOPMENT) {
29
+ console.log(actionName, message, customAttributes);
30
+ }
31
+ if (window && typeof window.newrelic !== 'undefined') {
32
+ // https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/addpageaction/
33
+ window.newrelic.addPageAction(actionName, { message, ...customAttributes });
34
+ }
35
+ }
36
+
37
+ function sendError(error, customAttributes) {
38
+ if (getSiteConfig().environment === EnvironmentTypes.DEVELOPMENT) {
39
+ console.error(error, customAttributes);
40
+ }
41
+ if (window && typeof window.newrelic !== 'undefined') {
42
+ // https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/noticeerror/
43
+ window.newrelic.noticeError(fixErrorLength(error), customAttributes);
44
+ }
45
+ }
46
+
47
+ function setCustomAttribute(name, value) {
48
+ if (getSiteConfig().environment === EnvironmentTypes.DEVELOPMENT) {
49
+ console.log(name, value);
50
+ }
51
+ if (window && typeof window.newrelic !== 'undefined') {
52
+ // https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/setcustomattribute/
53
+ window.newrelic.setCustomAttribute(name, value);
54
+ }
55
+ }
56
+
57
+ /**
58
+ * The NewRelicLoggingService is a concrete implementation of the logging service interface that
59
+ * sends messages to NewRelic that can be seen in NewRelic Browser and NewRelic Insights. When in
60
+ * development mode, all messages will instead be sent to the console.
61
+ *
62
+ * When you use `logError`, your errors will be checked to see if they're ignored *or* not.
63
+ * Not-ignored errors will appear under "JS errors" for your Browser application.
64
+ *
65
+ * ```
66
+ * SELECT * from JavaScriptError WHERE errorStatus is not null SINCE 10 days ago
67
+ * ```
68
+ *
69
+ * Ignored errors will appear in New Relic Insights as page actions, which can be queried:
70
+ *
71
+ * ```
72
+ * SELECT * from PageAction WHERE actionName = 'IGNORED_ERROR' SINCE 1 hour ago
73
+ * ```
74
+ *
75
+ * When using `logInfo`, these only appear in New Relic Insights when querying for page actions as
76
+ * follows:
77
+ *
78
+ * ```
79
+ * SELECT * from PageAction WHERE actionName = 'INFO' SINCE 1 hour ago
80
+ * ```
81
+ *
82
+ * You can also add your own custom metrics as an additional argument, or see the code to find
83
+ * other standard custom attributes. By default, userId is added (via setCustomAttribute) for logged
84
+ * in users via the auth service (AuthAxiosJwtService).
85
+ *
86
+ * Requires the NewRelic Browser JavaScript snippet.
87
+ *
88
+ * @implements {LoggingService}
89
+ * @memberof module:Logging
90
+ */
91
+ export default class NewRelicLoggingService {
92
+ constructor(options) {
93
+ const config = options ? options.config : undefined;
94
+ /*
95
+ String which is an explicit error message regex. If an error message matches the regex, the error
96
+ is considered an *ignored* error and submitted to New Relic as a page action - not an error.
97
+
98
+ Ignored error regexes are configured per frontend application (MFE).
99
+
100
+ The regex for all ignored errors are represented in the .env files as a single string. If you need to
101
+ ignore multiple errors, use the standard `|` regex syntax.
102
+
103
+ For example, here's a .env line which ignores two specific errors:
104
+
105
+ ignoredErrorRegex='^\\[frontend-auth\\] Unimportant Error|Specific non-critical error #[\\d]+'
106
+
107
+ This example would ignore errors with the following messages:
108
+
109
+ [frontend-app-generic] - Specific non-critical error #45678 happened.
110
+ [frontend-app-generic] - Specific non-critical error #93475 happened.
111
+ [frontend-auth] Unimportant Error: Browser strangeness occurred.
112
+
113
+ To test your regex additions, use a JS CLI environment (such as node) and run code like this:
114
+
115
+ x = new RegExp('^\\[frontend-auth\\] Unimportant Error|Specific non-critical error #[\\d]+');
116
+ '[frontend-app-generic] - Specific non-critical error #45678 happened.'.match(x);
117
+ '[frontend-auth] Unimportant Error: Browser strangeness occurred.'.match(x);
118
+ 'This error should not match anything!'.match(x);
119
+
120
+ For edx.org, add new error message regexes in edx-internal YAML as needed.
121
+ */
122
+ this.ignoredErrorRegexes = config ? config.ignoredErrorRegex : undefined;
123
+ }
124
+
125
+ /**
126
+ *
127
+ *
128
+ * @param {*} infoStringOrErrorObject
129
+ * @param {*} [customAttributes={}]
130
+ * @memberof NewRelicLoggingService
131
+ */
132
+ logInfo(infoStringOrErrorObject, customAttributes = {}) {
133
+ let message = infoStringOrErrorObject;
134
+ let customAttrs = customAttributes;
135
+ if (typeof infoStringOrErrorObject === 'object' && 'message' in infoStringOrErrorObject) {
136
+ /* Caller has passed in an error object to be logged as a page action. */
137
+ /* Extract the attributes and the message. */
138
+ const infoCustomAttributes = infoStringOrErrorObject.customAttributes || {};
139
+ customAttrs = { ...infoCustomAttributes, ...customAttributes };
140
+ message = infoStringOrErrorObject.message;
141
+ }
142
+ sendPageAction(pageActionNameInfo, message, customAttrs);
143
+ }
144
+
145
+ /**
146
+ *
147
+ *
148
+ * @param {*} errorStringOrObject
149
+ * @param {*} [customAttributes={}]
150
+ * @memberof NewRelicLoggingService
151
+ */
152
+ logError(errorStringOrObject, customAttributes = {}) {
153
+ const errorCustomAttributes = errorStringOrObject.customAttributes || {};
154
+ let allCustomAttributes = { ...errorCustomAttributes, ...customAttributes };
155
+ if (Object.keys(allCustomAttributes).length === 0) {
156
+ // noticeError expects undefined if there are no custom attributes.
157
+ allCustomAttributes = undefined;
158
+ }
159
+
160
+ /*
161
+ Separate the errors into ignored errors and other errors.
162
+ Ignored errors are logged via adding a page action.
163
+ Other errors are logged via noticeError and count as "JS Errors" for the application.
164
+ */
165
+ const errorMessage = errorStringOrObject.message || (typeof errorStringOrObject === 'string' ? errorStringOrObject : '');
166
+ if (this.ignoredErrorRegexes && errorMessage.match(this.ignoredErrorRegexes)) {
167
+ /* ignored error */
168
+ sendPageAction(pageActionNameIgnoredError, errorMessage, allCustomAttributes);
169
+ } else {
170
+ /* error! */
171
+ sendError(errorStringOrObject, allCustomAttributes);
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Sets a custom attribute that will be included with all subsequent log messages.
177
+ *
178
+ * @param {string} name
179
+ * @param {string|number|null} value
180
+ */
181
+ setCustomAttribute(name, value) {
182
+ setCustomAttribute(name, value);
183
+ }
184
+ }
@@ -0,0 +1,9 @@
1
+ export {
2
+ configureLogging,
3
+ getLoggingService,
4
+ logError,
5
+ logInfo,
6
+ resetLoggingService
7
+ } from './interface';
8
+ export { default as MockLoggingService } from './MockLoggingService';
9
+ export { default as NewRelicLoggingService } from './NewRelicLoggingService';