@edx/frontend-platform 4.6.2 → 4.6.3

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 (229) hide show
  1. package/package.json +1 -1
  2. package/.env.development +0 -30
  3. package/.env.test +0 -30
  4. package/.eslintignore +0 -6
  5. package/.eslintrc.js +0 -28
  6. package/.github/PULL_REQUEST_TEMPLATE.md +0 -13
  7. package/.github/workflows/add-depr-ticket-to-depr-board.yml +0 -19
  8. package/.github/workflows/add-remove-label-on-comment.yml +0 -20
  9. package/.github/workflows/ci.yml +0 -42
  10. package/.github/workflows/commitlint.yml +0 -10
  11. package/.github/workflows/lockfileversion-check.yml +0 -13
  12. package/.github/workflows/manual-publish.yml +0 -43
  13. package/.github/workflows/npm-deprecate.yml +0 -22
  14. package/.github/workflows/release.yml +0 -45
  15. package/.github/workflows/self-assign-issue.yml +0 -12
  16. package/.github/workflows/update-browserslist-db.yml +0 -12
  17. package/.nvmrc +0 -1
  18. package/.releaserc +0 -32
  19. package/catalog-info.yaml +0 -21
  20. package/dist/LICENSE +0 -661
  21. package/dist/README.md +0 -155
  22. package/dist/package.json +0 -86
  23. package/docs/addTagsPlugin.js +0 -10
  24. package/docs/auth-API.md +0 -114
  25. package/docs/decisions/0001-record-architecture-decisions.rst +0 -32
  26. package/docs/decisions/0002-frontend-base-design-goals.rst +0 -222
  27. package/docs/decisions/0003-consolidation-into-frontend-platform.rst +0 -71
  28. package/docs/decisions/0004-axios-caching-implementation.rst +0 -88
  29. package/docs/decisions/0005-token-null-after-successful-refresh.rst +0 -69
  30. package/docs/decisions/0006-middleware-support-for-http-clients.rst +0 -44
  31. package/docs/decisions/0007-javascript-file-configuration.rst +0 -143
  32. package/docs/how_tos/automatic-case-conversion.rst +0 -58
  33. package/docs/how_tos/caching.rst +0 -93
  34. package/docs/how_tos/i18n.rst +0 -305
  35. package/docs/removeExport.js +0 -24
  36. package/docs/template/edx/README.md +0 -12
  37. package/docs/template/edx/publish.js +0 -713
  38. package/docs/template/edx/static/fonts/OpenSans-Bold-webfont.eot +0 -0
  39. package/docs/template/edx/static/fonts/OpenSans-Bold-webfont.svg +0 -1830
  40. package/docs/template/edx/static/fonts/OpenSans-Bold-webfont.woff +0 -0
  41. package/docs/template/edx/static/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  42. package/docs/template/edx/static/fonts/OpenSans-BoldItalic-webfont.svg +0 -1830
  43. package/docs/template/edx/static/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  44. package/docs/template/edx/static/fonts/OpenSans-Italic-webfont.eot +0 -0
  45. package/docs/template/edx/static/fonts/OpenSans-Italic-webfont.svg +0 -1830
  46. package/docs/template/edx/static/fonts/OpenSans-Italic-webfont.woff +0 -0
  47. package/docs/template/edx/static/fonts/OpenSans-Light-webfont.eot +0 -0
  48. package/docs/template/edx/static/fonts/OpenSans-Light-webfont.svg +0 -1831
  49. package/docs/template/edx/static/fonts/OpenSans-Light-webfont.woff +0 -0
  50. package/docs/template/edx/static/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  51. package/docs/template/edx/static/fonts/OpenSans-LightItalic-webfont.svg +0 -1835
  52. package/docs/template/edx/static/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  53. package/docs/template/edx/static/fonts/OpenSans-Regular-webfont.eot +0 -0
  54. package/docs/template/edx/static/fonts/OpenSans-Regular-webfont.svg +0 -1831
  55. package/docs/template/edx/static/fonts/OpenSans-Regular-webfont.woff +0 -0
  56. package/docs/template/edx/static/scripts/linenumber.js +0 -25
  57. package/docs/template/edx/static/scripts/prettify/Apache-License-2.0.txt +0 -202
  58. package/docs/template/edx/static/scripts/prettify/lang-css.js +0 -2
  59. package/docs/template/edx/static/scripts/prettify/prettify.js +0 -28
  60. package/docs/template/edx/static/styles/jsdoc-default.css +0 -356
  61. package/docs/template/edx/static/styles/prettify-jsdoc.css +0 -111
  62. package/docs/template/edx/static/styles/prettify-tomorrow.css +0 -132
  63. package/docs/template/edx/tmpl/augments.tmpl +0 -10
  64. package/docs/template/edx/tmpl/container.tmpl +0 -196
  65. package/docs/template/edx/tmpl/details.tmpl +0 -143
  66. package/docs/template/edx/tmpl/example.tmpl +0 -2
  67. package/docs/template/edx/tmpl/examples.tmpl +0 -13
  68. package/docs/template/edx/tmpl/exceptions.tmpl +0 -32
  69. package/docs/template/edx/tmpl/layout.tmpl +0 -39
  70. package/docs/template/edx/tmpl/mainpage.tmpl +0 -10
  71. package/docs/template/edx/tmpl/members.tmpl +0 -38
  72. package/docs/template/edx/tmpl/method.tmpl +0 -131
  73. package/docs/template/edx/tmpl/modifies.tmpl +0 -14
  74. package/docs/template/edx/tmpl/params.tmpl +0 -131
  75. package/docs/template/edx/tmpl/properties.tmpl +0 -108
  76. package/docs/template/edx/tmpl/returns.tmpl +0 -19
  77. package/docs/template/edx/tmpl/source.tmpl +0 -8
  78. package/docs/template/edx/tmpl/tutorial.tmpl +0 -19
  79. package/docs/template/edx/tmpl/type.tmpl +0 -7
  80. package/env.config.js +0 -8
  81. package/jsdoc.json +0 -36
  82. package/openedx.yaml +0 -12
  83. package/service-interface.png +0 -0
  84. package/src/analytics/MockAnalyticsService.js +0 -71
  85. package/src/analytics/SegmentAnalyticsService.js +0 -243
  86. package/src/analytics/index.js +0 -12
  87. package/src/analytics/interface.js +0 -142
  88. package/src/auth/AxiosCsrfTokenService.js +0 -60
  89. package/src/auth/AxiosJwtAuthService.js +0 -364
  90. package/src/auth/AxiosJwtTokenService.js +0 -134
  91. package/src/auth/LocalForageCache.js +0 -78
  92. package/src/auth/MockAuthService.js +0 -285
  93. package/src/auth/index.js +0 -19
  94. package/src/auth/interceptors/createCsrfTokenProviderInterceptor.js +0 -37
  95. package/src/auth/interceptors/createJwtTokenProviderInterceptor.js +0 -38
  96. package/src/auth/interceptors/createProcessAxiosRequestErrorInterceptor.js +0 -20
  97. package/src/auth/interceptors/createRetryInterceptor.js +0 -72
  98. package/src/auth/interface.js +0 -309
  99. package/src/auth/utils.js +0 -105
  100. package/src/config.js +0 -327
  101. package/src/constants.js +0 -66
  102. package/src/i18n/countries.js +0 -57
  103. package/src/i18n/index.js +0 -123
  104. package/src/i18n/injectIntlWithShim.jsx +0 -45
  105. package/src/i18n/languages.js +0 -60
  106. package/src/i18n/lib.js +0 -282
  107. package/src/i18n/scripts/README.md +0 -29
  108. package/src/i18n/scripts/intl-imports.js +0 -259
  109. package/src/i18n/scripts/transifex-utils.js +0 -75
  110. package/src/index.js +0 -42
  111. package/src/initialize.js +0 -357
  112. package/src/logging/MockLoggingService.js +0 -31
  113. package/src/logging/NewRelicLoggingService.js +0 -181
  114. package/src/logging/index.js +0 -9
  115. package/src/logging/interface.js +0 -110
  116. package/src/pubSub.js +0 -47
  117. package/src/react/AppContext.jsx +0 -24
  118. package/src/react/AppProvider.jsx +0 -93
  119. package/src/react/AuthenticatedPageRoute.jsx +0 -60
  120. package/src/react/ErrorBoundary.jsx +0 -44
  121. package/src/react/ErrorPage.jsx +0 -76
  122. package/src/react/LoginRedirect.jsx +0 -16
  123. package/src/react/OptionalReduxProvider.jsx +0 -28
  124. package/src/react/PageRoute.jsx +0 -31
  125. package/src/react/hooks.js +0 -50
  126. package/src/react/index.js +0 -16
  127. package/src/scripts/GoogleAnalyticsLoader.js +0 -53
  128. package/src/scripts/index.js +0 -2
  129. package/src/testing/index.js +0 -9
  130. package/src/testing/initializeMockApp.js +0 -77
  131. package/src/testing/mockMessages.js +0 -21
  132. package/src/utils.js +0 -167
  133. /package/{dist/analytics → analytics}/MockAnalyticsService.js +0 -0
  134. /package/{dist/analytics → analytics}/MockAnalyticsService.js.map +0 -0
  135. /package/{dist/analytics → analytics}/SegmentAnalyticsService.js +0 -0
  136. /package/{dist/analytics → analytics}/SegmentAnalyticsService.js.map +0 -0
  137. /package/{dist/analytics → analytics}/index.js +0 -0
  138. /package/{dist/analytics → analytics}/index.js.map +0 -0
  139. /package/{dist/analytics → analytics}/interface.js +0 -0
  140. /package/{dist/analytics → analytics}/interface.js.map +0 -0
  141. /package/{dist/auth → auth}/AxiosCsrfTokenService.js +0 -0
  142. /package/{dist/auth → auth}/AxiosCsrfTokenService.js.map +0 -0
  143. /package/{dist/auth → auth}/AxiosJwtAuthService.js +0 -0
  144. /package/{dist/auth → auth}/AxiosJwtAuthService.js.map +0 -0
  145. /package/{dist/auth → auth}/AxiosJwtTokenService.js +0 -0
  146. /package/{dist/auth → auth}/AxiosJwtTokenService.js.map +0 -0
  147. /package/{dist/auth → auth}/LocalForageCache.js +0 -0
  148. /package/{dist/auth → auth}/LocalForageCache.js.map +0 -0
  149. /package/{dist/auth → auth}/MockAuthService.js +0 -0
  150. /package/{dist/auth → auth}/MockAuthService.js.map +0 -0
  151. /package/{dist/auth → auth}/index.js +0 -0
  152. /package/{dist/auth → auth}/index.js.map +0 -0
  153. /package/{dist/auth → auth}/interceptors/createCsrfTokenProviderInterceptor.js +0 -0
  154. /package/{dist/auth → auth}/interceptors/createCsrfTokenProviderInterceptor.js.map +0 -0
  155. /package/{dist/auth → auth}/interceptors/createJwtTokenProviderInterceptor.js +0 -0
  156. /package/{dist/auth → auth}/interceptors/createJwtTokenProviderInterceptor.js.map +0 -0
  157. /package/{dist/auth → auth}/interceptors/createProcessAxiosRequestErrorInterceptor.js +0 -0
  158. /package/{dist/auth → auth}/interceptors/createProcessAxiosRequestErrorInterceptor.js.map +0 -0
  159. /package/{dist/auth → auth}/interceptors/createRetryInterceptor.js +0 -0
  160. /package/{dist/auth → auth}/interceptors/createRetryInterceptor.js.map +0 -0
  161. /package/{dist/auth → auth}/interface.js +0 -0
  162. /package/{dist/auth → auth}/interface.js.map +0 -0
  163. /package/{dist/auth → auth}/utils.js +0 -0
  164. /package/{dist/auth → auth}/utils.js.map +0 -0
  165. /package/{dist/config.js → config.js} +0 -0
  166. /package/{dist/config.js.map → config.js.map} +0 -0
  167. /package/{dist/constants.js → constants.js} +0 -0
  168. /package/{dist/constants.js.map → constants.js.map} +0 -0
  169. /package/{dist/i18n → i18n}/countries.js +0 -0
  170. /package/{dist/i18n → i18n}/countries.js.map +0 -0
  171. /package/{dist/i18n → i18n}/index.js +0 -0
  172. /package/{dist/i18n → i18n}/index.js.map +0 -0
  173. /package/{dist/i18n → i18n}/injectIntlWithShim.js +0 -0
  174. /package/{dist/i18n → i18n}/injectIntlWithShim.js.map +0 -0
  175. /package/{dist/i18n → i18n}/languages.js +0 -0
  176. /package/{dist/i18n → i18n}/languages.js.map +0 -0
  177. /package/{dist/i18n → i18n}/lib.js +0 -0
  178. /package/{dist/i18n → i18n}/lib.js.map +0 -0
  179. /package/{dist/i18n → i18n}/scripts/README.md +0 -0
  180. /package/{dist/i18n → i18n}/scripts/intl-imports.js +0 -0
  181. /package/{dist/i18n → i18n}/scripts/intl-imports.js.map +0 -0
  182. /package/{dist/i18n → i18n}/scripts/transifex-utils.js +0 -0
  183. /package/{dist/i18n → i18n}/scripts/transifex-utils.js.map +0 -0
  184. /package/{dist/index.js → index.js} +0 -0
  185. /package/{dist/index.js.map → index.js.map} +0 -0
  186. /package/{dist/initialize.js → initialize.js} +0 -0
  187. /package/{dist/initialize.js.map → initialize.js.map} +0 -0
  188. /package/{dist/logging → logging}/MockLoggingService.js +0 -0
  189. /package/{dist/logging → logging}/MockLoggingService.js.map +0 -0
  190. /package/{dist/logging → logging}/NewRelicLoggingService.js +0 -0
  191. /package/{dist/logging → logging}/NewRelicLoggingService.js.map +0 -0
  192. /package/{dist/logging → logging}/index.js +0 -0
  193. /package/{dist/logging → logging}/index.js.map +0 -0
  194. /package/{dist/logging → logging}/interface.js +0 -0
  195. /package/{dist/logging → logging}/interface.js.map +0 -0
  196. /package/{dist/pubSub.js → pubSub.js} +0 -0
  197. /package/{dist/pubSub.js.map → pubSub.js.map} +0 -0
  198. /package/{dist/react → react}/AppContext.js +0 -0
  199. /package/{dist/react → react}/AppContext.js.map +0 -0
  200. /package/{dist/react → react}/AppProvider.js +0 -0
  201. /package/{dist/react → react}/AppProvider.js.map +0 -0
  202. /package/{dist/react → react}/AuthenticatedPageRoute.js +0 -0
  203. /package/{dist/react → react}/AuthenticatedPageRoute.js.map +0 -0
  204. /package/{dist/react → react}/ErrorBoundary.js +0 -0
  205. /package/{dist/react → react}/ErrorBoundary.js.map +0 -0
  206. /package/{dist/react → react}/ErrorPage.js +0 -0
  207. /package/{dist/react → react}/ErrorPage.js.map +0 -0
  208. /package/{dist/react → react}/LoginRedirect.js +0 -0
  209. /package/{dist/react → react}/LoginRedirect.js.map +0 -0
  210. /package/{dist/react → react}/OptionalReduxProvider.js +0 -0
  211. /package/{dist/react → react}/OptionalReduxProvider.js.map +0 -0
  212. /package/{dist/react → react}/PageRoute.js +0 -0
  213. /package/{dist/react → react}/PageRoute.js.map +0 -0
  214. /package/{dist/react → react}/hooks.js +0 -0
  215. /package/{dist/react → react}/hooks.js.map +0 -0
  216. /package/{dist/react → react}/index.js +0 -0
  217. /package/{dist/react → react}/index.js.map +0 -0
  218. /package/{dist/scripts → scripts}/GoogleAnalyticsLoader.js +0 -0
  219. /package/{dist/scripts → scripts}/GoogleAnalyticsLoader.js.map +0 -0
  220. /package/{dist/scripts → scripts}/index.js +0 -0
  221. /package/{dist/scripts → scripts}/index.js.map +0 -0
  222. /package/{dist/testing → testing}/index.js +0 -0
  223. /package/{dist/testing → testing}/index.js.map +0 -0
  224. /package/{dist/testing → testing}/initializeMockApp.js +0 -0
  225. /package/{dist/testing → testing}/initializeMockApp.js.map +0 -0
  226. /package/{dist/testing → testing}/mockMessages.js +0 -0
  227. /package/{dist/testing → testing}/mockMessages.js.map +0 -0
  228. /package/{dist/utils.js → utils.js} +0 -0
  229. /package/{dist/utils.js.map → utils.js.map} +0 -0
package/dist/README.md DELETED
@@ -1,155 +0,0 @@
1
- [![Build Status](https://github.com/openedx/frontend-platform/actions/workflows/ci.yml/badge.svg)](https://github.com/openedx/frontend-platform/actions/workflows/ci.yml)
2
- [![Codecov](https://img.shields.io/codecov/c/github/edx/frontend-platform)](https://codecov.io/gh/edx/frontend-platform)
3
- [![NPM Version](https://img.shields.io/npm/v/@edx/frontend-platform.svg)](https://www.npmjs.com/package/@edx/frontend-platform)
4
- [![npm_downloads](https://img.shields.io/npm/dt/@edx/frontend-platform.svg)](https://www.npmjs.com/package/@edx/frontend-platform)
5
- [![license](https://img.shields.io/npm/l/@edx/frontend-platform.svg)](https://github.com/openedx/frontend-platform/blob/master/LICENSE)
6
- [![semantic release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
7
-
8
- # Overview
9
-
10
- See the [GitHub Pages site for the complete documentation](https://openedx.github.io/frontend-platform/).
11
-
12
- frontend-platform is a modest application framework for Open edX micro-frontend applications and their supporting libraries. It provides several foundational services that all Open edX micro-frontends should have:
13
-
14
- | Service | Module location |
15
- |------------------------------------|----------------------------------|
16
- | Analytics | @edx/frontend-platform/analytics |
17
- | Logging | @edx/frontend-platform/logging |
18
- | Authenticated API client (auth) | @edx/frontend-platform/auth |
19
- | Internationalization (i18n) | @edx/frontend-platform/i18n |
20
- | Misc (init, config, pubSub, utils) | @edx/frontend-platform |
21
-
22
- -------------------------------------------------------------------------
23
-
24
- In addition, frontend-platform provides an extensible application initialization lifecycle to help manage the configuration of the above services, freeing application developers to focus on feature development.
25
-
26
- ## Getting started
27
-
28
- ### One-time setup if you have not upgraded node/npm
29
- IMPORTANT: There is now a new node/npm version being used by frontend-platform as of
30
- https://github.com/openedx/frontend-platform/pull/259
31
-
32
- #### Install nvm
33
- This is highly recommended to be able to leverage different node/npm versions.
34
- For a some time, different repositories may be using different versions of node/npm.
35
-
36
- Alternatively, please install node16 and npm8 for use with this repository.
37
-
38
- #### Switch to node/npm version for this repo
39
- ```nvm use```
40
- if you don't have the right node/npm versions, nvm will instruct you to install those
41
-
42
- #### Clean out old node modules and reinstall
43
- This step is needed because node now uses a different package lock format, and it's important to reinstall
44
- dependencies based on this new package file. Delete node_modules, and issue an `npm ci`
45
-
46
-
47
- ### Standard getting started steps
48
-
49
- 1. `npm install`
50
- 2. `npm start`
51
- 3. Open http://localhost:8080 to view the example app.
52
-
53
- ## Architecture
54
-
55
- The four foundational services listed above (analytics, auth, i18n, and logging) are provided as imports to applications via frontend-platform's API layer. The initialization sequence creates an instance of each service and exposes its methods as functional exports, creating a layer of abstraction between service implementations and their usage in application code.
56
-
57
- Each type of service has a documented API contract which service implementations must fulfill. This allows different service implementations to be used as necessary without updates to consuming applications.
58
-
59
- ### Service architecture
60
-
61
- Internally, service implementations are strictly isolated from the rest of the platform. They are classes that take their dependencies as arguments to their constructor. This means, for instance, if analytics depends on logging, it takes a reference to an instance fulfilling the `LoggingService` interface as an option when it's instantiated. It cannot import from the logging module directly. Put another way, the default service implementations may be co-located with the service interfaces for convenience, but they can theoretically live in their own repository and it wouldn't require any refactoring.
62
-
63
- Likewise, platform code should not make use of service methods that are not part of the documented interface for the same reasons.
64
-
65
- ### Application initialization
66
-
67
- frontend-platform provides an `initialize()` function which bootstraps and configures an application. The `initialize()` function uses a set of [sensible defaults](https://en.wikipedia.org/wiki/Convention_over_configuration) unless otherwise specified, bootstrapping the application with services reflecting Open edX's best practices around analytics, authentication, internationalization, and logging.
68
-
69
- The initialization process proceeds in a series of phases, giving the initializing application code opportunities to hook into the process and do custom setup as desired:
70
-
71
- - Before initialization
72
- - Pub/Sub initialized
73
- - Environment config document loaded
74
- - Logging service initialized
75
- - Authentication service initialized
76
- - Analytics service initialized
77
- - Internationalization service initialized
78
- - Application ready
79
-
80
- Most applications won't need to do anything special at all.
81
-
82
- ### Application configuration
83
-
84
- When the application loads, a list of known environment variables is loaded from `process.env` into an object which it exposes via `getConfig` - the point here is primarily to isolate our code from usages of `process.env` which may not always be the way we choose to configure our apps. The application initialization lifecycle supports runtime configuration as well via the `config` handler, documented in the [initialize function](https://edx.github.io/frontend-platform/module-Initialization.html#~initialize). If you want to get a variable into the config that it’s not expecting, you can use [`mergeConfig`](https://edx.github.io/frontend-platform/module-Config.html#~mergeConfig) during initialization to add it in from `process.env`.
85
-
86
- Such an example might look like this:
87
-
88
- ```
89
- initialize({
90
- // ... other initialization options
91
- handlers: {
92
- config: () => {
93
- mergeConfig({
94
- CUSTOM_VARIABLE: process.env.CUSTOM_VARIABLE || null,
95
- }, 'Custom app config');
96
- },
97
- },
98
- });
99
- ```
100
-
101
- When using runtime configuration via `mergeConfig` noted above, `getConfig` must be called within a component's render lifecycle for the added keys and values to be returned in the configuration object. If `getConfig` is called outside of a component's render lifecycle, the custom configuration key/value pairs will not initially be part of the object returned by `getConfig`. For example:
102
-
103
- ```jsx
104
- import { getConfig } from '@edx/frontend-platform/config';
105
-
106
- // The runtime configuration `CUSTOM_VARIABLE` added in the above code snippet will not appear here. This is
107
- // because `getConfig` is called before `mergeConfig` is executed to add the custom runtime configuration.
108
- console.log(getConfig().CUSTOM_VARIABLE); // returns undefined
109
-
110
- const ExampleComponent = () => {
111
- // This returns the value as expected since it is called after `mergeConfig` has already been executed.
112
- console.log(getConfig().CUSTOM_VARIABLE)
113
- };
114
- ```
115
-
116
- ### Service interfaces
117
-
118
- Each service (analytics, auth, i18n, logging) provided by frontend-platform has an API contract which all implementations of that service are guaranteed to fulfill. Applications that use frontend-platform can use its configured services via a convenient set of exported functions. An application that wants to use the service interfaces need only initialize them via the initialize() function, optionally providing custom service interfaces as desired (you probably won't need to).
119
-
120
- ![Service interface](service-interface.png)
121
-
122
- ### Service implementations
123
-
124
- This repository contains default service implementations for convenience. These implementations are co-located with their consuming service interfaces for ease of development, though the two should remain _strictly_ modular and separate.
125
-
126
- The included service implementations are:
127
-
128
- - New Relic (logging)
129
- - Segment (analytics)
130
- - Axios/JWT (auth)
131
- - React Intl (i18n)
132
-
133
- NOTE: As of this writing, i18n is _not_ configurable. The `initialize()` function does not allow applications to supply an alternate i18n implementation; this is because the interface and implementation for i18n has not yet been separated and modularized.
134
-
135
- # Local Development & Testing Locally
136
-
137
- When making changes to frontend-platform, be sure to manually run the included example app located in `./example`. The example app includes 2 routes to test for both unauthenticated and authenticated users. To start the example app, run `npm start` from the root directory.
138
-
139
- If you want to test changes to frontend-platform against a micro-frontend locally, follow the directions here: https://github.com/openedx/frontend-build#local-module-configuration-for-webpack
140
-
141
- # Production Deployment Strategy
142
-
143
- For any MFE built on top of the frontend-platform, the deployment strategy will be something like the following:
144
-
145
- 1. Run the build script with environment variables on the command line to pass in any relevant config. Example:
146
-
147
- ```bash
148
- NODE_ENV=development BASE_URL=open.edx.org ETC=etc npm run build
149
- ```
150
-
151
- This will create a dist/ directory that contains the deployable artifacts.
152
-
153
- 2. Copy the contents of dist/ to a web server.
154
-
155
- 3. Configure the platform to point at your MFE. (details on this coming soon)
package/dist/package.json DELETED
@@ -1,86 +0,0 @@
1
- {
2
- "name": "@edx/frontend-platform",
3
- "version": "4.6.2",
4
- "description": "Foundational application framework for Open edX micro-frontend applications.",
5
- "main": "index.js",
6
- "publishConfig": {
7
- "access": "public"
8
- },
9
- "sideEffects": false,
10
- "scripts": {
11
- "build": "make build",
12
- "docs": "jsdoc -c jsdoc.json",
13
- "docs-watch": "nodemon -w src -w docs/template -w README.md -e js,jsx --exec npm run docs",
14
- "lint": "fedx-scripts eslint --ext .js --ext .jsx .",
15
- "snapshot": "fedx-scripts jest --updateSnapshot",
16
- "start": "fedx-scripts webpack-dev-server --progress",
17
- "test": "fedx-scripts jest --coverage",
18
- "test:watch": "npm run test -- --watch"
19
- },
20
- "bin": {
21
- "intl-imports.js": "i18n/scripts/intl-imports.js",
22
- "transifex-utils.js": "i18n/scripts/transifex-utils.js"
23
- },
24
- "repository": {
25
- "type": "git",
26
- "url": "git+https://github.com/openedx/frontend-platform.git"
27
- },
28
- "author": "edX",
29
- "license": "AGPL-3.0",
30
- "bugs": {
31
- "url": "https://github.com/openedx/frontend-platform/issues"
32
- },
33
- "homepage": "https://github.com/openedx/frontend-platform#readme",
34
- "devDependencies": {
35
- "@edx/brand": "npm:@edx/brand-openedx@1.2.0",
36
- "@edx/browserslist-config": "1.2.0",
37
- "@edx/frontend-build": "12.9.3",
38
- "@edx/paragon": "^20.44.0",
39
- "@testing-library/react-hooks": "^8.0.1",
40
- "@wojtekmaj/enzyme-adapter-react-17": "0.8.0",
41
- "axios-mock-adapter": "^1.21.5",
42
- "core-js": "3.32.0",
43
- "enzyme": "3.11.0",
44
- "husky": "8.0.3",
45
- "jsdoc": "^4.0.0",
46
- "nodemon": "2.0.22",
47
- "prop-types": "15.8.1",
48
- "react": "17.0.2",
49
- "react-dom": "17.0.2",
50
- "react-redux": "7.2.9",
51
- "react-router-dom": "5.3.4",
52
- "redux": "4.2.1",
53
- "regenerator-runtime": "0.13.11"
54
- },
55
- "dependencies": {
56
- "@cospired/i18n-iso-languages": "4.1.0",
57
- "@formatjs/intl-pluralrules": "4.3.3",
58
- "@formatjs/intl-relativetimeformat": "10.0.1",
59
- "axios": "0.27.2",
60
- "axios-cache-interceptor": "0.10.7",
61
- "form-urlencoded": "4.1.4",
62
- "glob": "7.2.3",
63
- "history": "4.10.1",
64
- "i18n-iso-countries": "4.3.1",
65
- "jwt-decode": "3.1.2",
66
- "localforage": "1.10.0",
67
- "localforage-memoryStorageDriver": "0.9.2",
68
- "lodash.camelcase": "4.3.0",
69
- "lodash.memoize": "4.1.2",
70
- "lodash.merge": "4.6.2",
71
- "lodash.snakecase": "4.1.1",
72
- "pubsub-js": "1.9.4",
73
- "react-intl": "^5.25.0",
74
- "universal-cookie": "4.0.4"
75
- },
76
- "peerDependencies": {
77
- "@edx/frontend-build": ">= 8.1.0 || ^12.9.0-alpha.1",
78
- "@edx/paragon": ">= 10.0.0 < 22.0.0",
79
- "prop-types": "^15.7.2",
80
- "react": "^16.9.0 || ^17.0.0",
81
- "react-dom": "^16.9.0 || ^17.0.0",
82
- "react-redux": "^7.1.1",
83
- "react-router-dom": "^5.0.1",
84
- "redux": "^4.0.4"
85
- }
86
- }
@@ -1,10 +0,0 @@
1
- exports.defineTags = function (dictionary) {
2
- dictionary.defineTag("service", {
3
- mustHaveValue: true,
4
- canHaveType: false,
5
- canHaveName: true,
6
- onTagged: function (doclet, tag) {
7
- doclet.service = tag.value;
8
- }
9
- });
10
- };
package/docs/auth-API.md DELETED
@@ -1,114 +0,0 @@
1
- <a name="LoginRedirect"></a>
2
-
3
- ## LoginRedirect : <code>ReactComponent</code>
4
- **Kind**: global class
5
- <a name="redirectToLogin"></a>
6
-
7
- ## redirectToLogin(redirectUrl)
8
- Redirect the user to login
9
-
10
- **Kind**: global function
11
-
12
- | Param | Type | Description |
13
- | --- | --- | --- |
14
- | redirectUrl | <code>string</code> | the url to redirect to after login |
15
-
16
- <a name="redirectToLogout"></a>
17
-
18
- ## redirectToLogout(redirectUrl)
19
- Redirect the user to logout
20
-
21
- **Kind**: global function
22
-
23
- | Param | Type | Description |
24
- | --- | --- | --- |
25
- | redirectUrl | <code>string</code> | the url to redirect to after logout |
26
-
27
- <a name="getAuthenticatedApiClient"></a>
28
-
29
- ## getAuthenticatedApiClient(config) ⇒ [<code>HttpClient</code>](#HttpClient)
30
- Gets the apiClient singleton which is an axios instance.
31
-
32
- **Kind**: global function
33
- **Returns**: [<code>HttpClient</code>](#HttpClient) - Singleton. A configured axios http client
34
-
35
- | Param | Type | Description |
36
- | --- | --- | --- |
37
- | config | <code>object</code> | |
38
- | [config.appBaseUrl] | <code>string</code> | |
39
- | [config.authBaseUrl] | <code>string</code> | |
40
- | [config.loginUrl] | <code>string</code> | |
41
- | [config.logoutUrl] | <code>string</code> | |
42
- | [config.loggingService] | <code>object</code> | requires logError and logInfo methods |
43
- | [config.refreshAccessTokenEndpoint] | <code>string</code> | |
44
- | [config.accessTokenCookieName] | <code>string</code> | |
45
- | [config.csrfTokenApiPath] | <code>string</code> | |
46
-
47
- <a name="getAuthenticatedUser"></a>
48
-
49
- ## getAuthenticatedUser() ⇒ [<code>Promise.&lt;UserData&gt;</code>](#UserData) \| <code>Promise.&lt;null&gt;</code>
50
- Gets the authenticated user's access token. Resolves to null if the user is unauthenticated.
51
-
52
- **Kind**: global function
53
- **Returns**: [<code>Promise.&lt;UserData&gt;</code>](#UserData) \| <code>Promise.&lt;null&gt;</code> - Resolves to the user's access token if they are logged in.
54
- <a name="ensureAuthenticatedUser"></a>
55
-
56
- ## ensureAuthenticatedUser(route) ⇒ [<code>Promise.&lt;UserData&gt;</code>](#UserData)
57
- Ensures a user is authenticated. It will redirect to login when not authenticated.
58
-
59
- **Kind**: global function
60
-
61
- | Param | Type | Description |
62
- | --- | --- | --- |
63
- | route | <code>string</code> | to return user after login when not authenticated. |
64
-
65
- <a name="PrivateRoute"></a>
66
-
67
- ## PrivateRoute() : <code>ReactComponent</code>
68
- **Kind**: global function
69
- <a name="HttpClient"></a>
70
-
71
- ## HttpClient
72
- A configured axios client. See axios docs for more
73
- info https://github.com/axios/axios. All the functions
74
- below accept isPublic and isCsrfExempt in the request
75
- config options. Setting these to true will prevent this
76
- client from attempting to refresh the jwt access token
77
- or a csrf token respectively.
78
-
79
- ```
80
- // A public endpoint (no jwt token refresh)
81
- apiClient.get('/path/to/endpoint', { isPublic: true });
82
- ```
83
-
84
- ```
85
- // A csrf exempt endpoint
86
- apiClient.post('/path/to/endpoint', { data }, { isCsrfExempt: true });
87
- ```
88
-
89
- **Kind**: global typedef
90
- **Properties**
91
-
92
- | Name | Type | Description |
93
- | --- | --- | --- |
94
- | get | <code>function</code> | |
95
- | head | <code>function</code> | |
96
- | options | <code>function</code> | |
97
- | delete | <code>function</code> | (csrf protected) |
98
- | post | <code>function</code> | (csrf protected) |
99
- | put | <code>function</code> | (csrf protected) |
100
- | patch | <code>function</code> | (csrf protected) |
101
-
102
- <a name="UserData"></a>
103
-
104
- ## UserData
105
- **Kind**: global typedef
106
- **Properties**
107
-
108
- | Name | Type |
109
- | --- | --- |
110
- | userId | <code>string</code> |
111
- | username | <code>string</code> |
112
- | roles | <code>array</code> |
113
- | administrator | <code>bool</code> |
114
-
@@ -1,32 +0,0 @@
1
- 1. Record Architecture Decisions
2
- --------------------------------
3
-
4
- Status
5
- ------
6
-
7
- Accepted
8
-
9
- Context
10
- -------
11
-
12
- We would like to keep a historical record on the architectural
13
- decisions we make with this app as it evolves over time.
14
-
15
- Decision
16
- --------
17
-
18
- We will use Architecture Decision Records, as described by
19
- Michael Nygard in `Documenting Architecture Decisions`_
20
-
21
- .. _Documenting Architecture Decisions: http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions
22
-
23
- Consequences
24
- ------------
25
-
26
- See Michael Nygard's article, linked above.
27
-
28
- References
29
- ----------
30
-
31
- * https://resources.sei.cmu.edu/asset_files/Presentation/2017_017_001_497746.pdf
32
- * https://github.com/npryce/adr-tools/tree/master/doc/adr
@@ -1,222 +0,0 @@
1
- frontend-base Design Goals
2
- ==========================
3
-
4
- Status
5
- ------
6
-
7
- Accepted
8
-
9
- Goals
10
- -----
11
-
12
- The creation of frontend-base framework was motivated by a few desires
13
- and concerns.
14
-
15
- Code reuse
16
- ~~~~~~~~~~
17
-
18
- We wanted to "DRY" up boilerplate code that was being copied from
19
- repository to repository each time we created a new micro-frontend.
20
-
21
- We observed that as the code was copied around, it tended to drift, and
22
- later implementations had different - and often better - best practices
23
- than the ones that came before. Worse, if a fix went in to an older
24
- application, we had no way to easily carry that forward. This meant we
25
- had no guarantee that our applications had the correct infrastructure
26
- for analytics, logging, i18n, error handling, observability, and
27
- authentication.
28
-
29
- Configuration standardization
30
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31
-
32
- Similar to code drift, we found our set of environment configuration
33
- variables were not standardized, creating a maintenance overhead and the
34
- potential for 1) applications being given variables they were unlikely
35
- to need, or worse 2) lacking required variables. We observed that it was
36
- tedious and error prone to add a new variable across multiple
37
- applications.
38
-
39
- Ease of use
40
- ~~~~~~~~~~~
41
-
42
- In writing some of our first micro-frontends, it was becoming difficult
43
- to pass some information around the application (environment
44
- configuration, authenticated user data, and the authenticated API
45
- client, specifically), while still maintaining a sense of modularity. We
46
- were using dependency injection, but it was a heavy-handed
47
- implementation that involved a hierarchical set of "configure()" methods
48
- to help pass the data around. We wanted to address this and make it
49
- straightforward to use top-level data effortlessly.
50
-
51
- .. _consistency-vs-flexibility:
52
-
53
- Consistency vs. flexibility
54
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
55
-
56
- We were concerned - with the creation of a "base" library to contain and
57
- tie together all this code - that we would hamper our ability to enable
58
- experimentation and independently deployed applications, one of our most
59
- fundamental goals in adopting a micro-frontend architecture.
60
-
61
- This functions on two levels: 1) we wanted to maintain our ability to
62
- allow new micro-frontends to forge ahead and experiment with new
63
- technology and library features, and 2) we also wanted to ensure that
64
- our "base" library was not too prescriptive about exactly what it means
65
- to be an Open edX micro-frontend.
66
-
67
- Exploration of frontend pluggability
68
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
69
-
70
- In preparation for efforts related to enabling frontend pluggability, we
71
- felt it valuable to create a layer of abstraction for applications that
72
- enabled application pages to start being "plugged into" the top-level
73
- application bootstrapping and lifecycle management code. In doing so, we
74
- hoped to start understanding what we might encounter as we move forward
75
- with pluggability. (This is the softest of these desires, but a helpful
76
- learning experience)
77
-
78
- Implementation
79
- --------------
80
-
81
- ``frontend-base`` is an attempt to address the above desires and
82
- concerns.
83
-
84
- Addressing code reuse
85
- ~~~~~~~~~~~~~~~~~~~~~
86
-
87
- It provides a home for application initialization/configuration code,
88
- allowing us to use semantic versioning to manage its implementations
89
- across our micro-frontends. This code will cease to be copied from
90
- repository to repository, and will instead be imported from published
91
- versions of ``frontend-base``. This allows us to know at a glance what
92
- boilerplate features/bug fixes a given application has, and a clear,
93
- documented path to upgrade and deal with breaking changes.
94
-
95
- Addressing ease of use
96
- ~~~~~~~~~~~~~~~~~~~~~~
97
-
98
- ``frontend-base`` makes use of a singleton class - ``App`` which can be
99
- imported into arbitrary code and provides access to commonly used sets
100
- of data, such as configuration variables, authenticated user
101
- information, and an API client. This makes it trivial to access all this
102
- top level data, removing the need to manually pass it around.
103
-
104
- Addressing configuration standardization
105
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
106
-
107
- The library ingests and provides access to a known set of environment
108
- variable-based configuration variables. It validates that these
109
- variables have been set with non-\ ``undefined`` values, and provides
110
- utility methods for performing similar checks on any custom
111
- configuration that a consuming application may need. It provides
112
- extension hooks for doing dynamic configuration at runtime, if
113
- necessary, leaving the door open for other configuration methods. An
114
- arbitrary piece of application code can assert that it requires certain
115
- variables, throwing runtime exceptions immediately if they weren't set.
116
- This gives developers immediate, definitive feedback of any
117
- configuration issues in their deployment pipelines.
118
-
119
- .. _addressing-consistency-vs-flexibility:
120
-
121
- Addressing consistency vs. flexibility
122
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
123
-
124
- ``frontend-base`` is published to npm as ES6 modules with
125
- ``peerDependencies`` in its package.json. This means that consuming apps
126
- are told exactly what versions of supporting libraries
127
- (``@edx/frontend-auth``, ``@edx/frontend-i18n``, ``@edx/paragon``,
128
- React, etc.) are compatible with a given version of ``frontend-base``.
129
- Beyond that, applications are free to use any compatible version. This
130
- prevents ``frontend-base`` from being a bottleneck for updating library
131
- versions, and helps application authors avoid situations where they have
132
- to consume multiple breaking changes just to get a new feature in *one*
133
- supporting library.
134
-
135
- The library has an extensible and fully customizable initialization
136
- sequence. Any phase of initialization can be modified to support
137
- unforeseen use cases while maintaining the framework as a whole.
138
-
139
- Addressing exploration of frontend pluggability
140
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
141
-
142
- The process of creating ``frontend-base`` was conducted using
143
- ``@edx/frontend-app-profile`` as a test bed. As a result, we learned how
144
- to modularize the application-specific code in the Profile
145
- micro-frontend to allow it to be consumed by a more generic application
146
- framework. We also, tangentially, explored ways of customizing the
147
- header and footer and ensured that they could be reasonably separated
148
- from both the framework and the application code.
149
-
150
- This resulted in a loose coupling of the ``frontend-base`` framework and
151
- the application code it was consuming. The UI modules (header, footer,
152
- and profile page) are starting to coalesce around a simple interface of
153
- exports:
154
-
155
- - A default export of the top-level React component.
156
- - A ``messages`` export for i18n resources.
157
- - A ``reducer`` export for Redux reducers.
158
- - A ``saga`` export for the redux-saga middleware.
159
-
160
- Furthermore, as part of ``frontend-base``, we were able to separate out
161
- the application initialization sequence from the rendering of the
162
- application UI. This means that - with the exception of its optional
163
- React component helpers and our usage of @edx/frontend-i18n -
164
- frontend-base is nearly UI framework agnostic. It can initialize
165
- completely without being concerned about the UI framework in use, and
166
- then gracefully handoff to React or whichever else.
167
-
168
- Adoption
169
- --------
170
-
171
- We intend to update existing micro-frontends to make use of
172
- ``frontend-base``. We've started with frontend-app-profile and are
173
- following up with frontend-app-payment. Newer micro-frontends will be
174
- created with it as a dependency. Other, older micro-frontends will be
175
- prioritized over time.
176
-
177
- Consequences
178
- ------------
179
-
180
- The library should go a long way toward standardizing our application
181
- initialization code and helping us keep all our micro-frontends up to
182
- date. That's the big win.
183
-
184
- It also provides micro-frontend developers with a strong, flexible
185
- foundation on which to build their applications. As we discover bugs or
186
- new, fundamental features that we want our apps to be able to handle, we
187
- have one centralized place to implement them.
188
-
189
- It was also a useful exploration of pluggability, abstraction, and
190
- separation of concerns, which should help inform our work going forward.
191
-
192
- Furthermore, reading the tea leaves a bit, we can foresee a future where
193
- our Open edX micro-frontends are lazy-loaded modules that are plugged
194
- into frontend-base at runtime, allowing independently deployable 'pages'
195
- of a larger single-page app, which should pay dividends in user
196
- experience and application runtime performance.
197
-
198
- Concerns and Limitations
199
- ------------------------
200
-
201
- The choice to create ``frontend-base`` involves a few concerns:
202
-
203
- One, we hope that we've made a framework that is simple, unobtrustive,
204
- extensible, and effective. This is, admittedly, hard to do, and it's
205
- possible that as time goes on we'll find that it has certain limitations
206
- and may need to revisit it. Specifically, it remains to be seen the
207
- extent to which it is compatible with GatsbyJS's initialization hooks
208
- (``onClientInit`` and ``wrapRootElement``, for instance).
209
-
210
- Two, the library also assumes that environment-variable based
211
- configuration - via ``process.env``, is sufficient for most of our needs
212
- across the organization. This seems to be the case, but has yet to be
213
- scrutinized. While the library allows for dynamic run-time configuration
214
- or replacing the environment variable configuration, it does not
215
- postulate on or provide another mechanism for doing so.
216
-
217
- Three, ``peerDependencies`` manifest as warnings, not errors, and can be
218
- easily ignored. In general it would be better if there was stronger
219
- enforcement of frontend-base's peer dependency requirements, but we're
220
- limited by what ``npm`` will provide. It's slightly concerning that a
221
- dependency could be incompatible and we potentially wouldn't know it
222
- until runtime.