@openedx/frontend-base 1.0.0-alpha.0 → 1.0.0-alpha.2

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 (164) hide show
  1. package/config/types.js +0 -2
  2. package/config/webpack/plugins/html-webpack-new-relic-plugin/test/HtmlWebpackNewRelicPlugin.test.js +66 -0
  3. package/package.json +8 -1
  4. package/runtime/__mocks__/file.js +1 -0
  5. package/runtime/__mocks__/svg.js +1 -0
  6. package/runtime/__mocks__/universal-cookie.js +6 -0
  7. package/runtime/analytics/interface.test.js +242 -0
  8. package/runtime/auth/AxiosJwtAuthService.test.jsx +1076 -0
  9. package/runtime/auth/interceptors/createRetryInterceptor.test.js +23 -0
  10. package/runtime/config/getExternalLinkUrl.test.js +76 -0
  11. package/runtime/i18n/lib.test.js +230 -0
  12. package/runtime/initialize.async.function.config.test.js +43 -0
  13. package/runtime/initialize.const.config.test.js +41 -0
  14. package/runtime/initialize.function.config.test.js +41 -0
  15. package/runtime/initialize.test.js +356 -0
  16. package/runtime/logging/NewRelicLoggingService.test.js +214 -0
  17. package/runtime/react/AuthenticatedPageRoute.test.jsx +135 -0
  18. package/runtime/react/ErrorBoundary.test.jsx +83 -0
  19. package/runtime/react/SiteProvider.test.jsx +66 -0
  20. package/runtime/react/hooks.test.jsx +104 -0
  21. package/runtime/routing/utils.test.ts +7 -0
  22. package/runtime/scripts/GoogleAnalyticsLoader.test.ts +77 -0
  23. package/runtime/site.config.test.tsx +33 -0
  24. package/runtime/slots/Slot.test.tsx +40 -0
  25. package/runtime/slots/layout/DefaultSlotLayout.test.tsx +31 -0
  26. package/runtime/slots/layout/hooks.test.tsx +178 -0
  27. package/runtime/slots/layout/utils.test.ts +67 -0
  28. package/runtime/slots/types.ts +1 -0
  29. package/runtime/slots/utils.test.ts +64 -0
  30. package/runtime/slots/utils.ts +28 -9
  31. package/runtime/testing/initializeMockApp.test.ts +66 -0
  32. package/runtime/utils.test.js +116 -0
  33. package/shell/Logo.test.tsx +32 -0
  34. package/shell/__mocks__/file.js +1 -0
  35. package/shell/__mocks__/svg.js +1 -0
  36. package/shell/__mocks__/universal-cookie.js +6 -0
  37. package/shell/app.ts +14 -0
  38. package/shell/dev/devHome/app.ts +2 -2
  39. package/shell/dev/slotShowcase/app.tsx +9 -9
  40. package/shell/header/app.tsx +3 -3
  41. package/shell/router/createRouter.test.tsx +50 -0
  42. package/shell/router/getAppRoutes.test.tsx +59 -0
  43. package/shell/site.config.dev.tsx +3 -3
  44. package/shell/site.config.test.tsx +16 -0
  45. package/tools/dist/cli/intl-imports.test.js +146 -0
  46. package/tools/dist/cli/openedx.js +1 -15
  47. package/tools/dist/cli/utils/printUsage.js +0 -9
  48. package/tools/dist/types.js +0 -2
  49. package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/test/HtmlWebpackNewRelicPlugin.test.js +66 -0
  50. package/types.ts +1 -1
  51. package/eslint.config.js +0 -18
  52. package/frontend-base.d.ts +0 -8
  53. package/jest.config.js +0 -7
  54. package/openedx-frontend-base.tgz +0 -0
  55. package/test-site/app.d.ts +0 -15
  56. package/test-site/dist/176.436443549ebb858db483.js +0 -2
  57. package/test-site/dist/176.436443549ebb858db483.js.map +0 -1
  58. package/test-site/dist/362.536eff787d2380fe246c.js +0 -2
  59. package/test-site/dist/362.536eff787d2380fe246c.js.map +0 -1
  60. package/test-site/dist/653.486966b108d224551296.js +0 -2
  61. package/test-site/dist/653.486966b108d224551296.js.map +0 -1
  62. package/test-site/dist/74e025d3fe9a7b7f8503054e2563b353.jpg +0 -0
  63. package/test-site/dist/806.323cf6496ad0a7fe73a7.js +0 -3
  64. package/test-site/dist/806.323cf6496ad0a7fe73a7.js.LICENSE.txt +0 -106
  65. package/test-site/dist/806.323cf6496ad0a7fe73a7.js.map +0 -1
  66. package/test-site/dist/95ec738c0b7faac5b5c9126794446bbd.svg +0 -4
  67. package/test-site/dist/app.612058b36c74787759ac.css +0 -61
  68. package/test-site/dist/app.612058b36c74787759ac.css.map +0 -1
  69. package/test-site/dist/app.612058b36c74787759ac.js +0 -2
  70. package/test-site/dist/app.612058b36c74787759ac.js.map +0 -1
  71. package/test-site/dist/cb28cdb1468c915e27e5cec9af64f22f.svg +0 -1
  72. package/test-site/dist/index.html +0 -1
  73. package/test-site/dist/report.html +0 -39
  74. package/test-site/dist/runtime.c7aeaf7b967496cb076f.js +0 -2
  75. package/test-site/dist/runtime.c7aeaf7b967496cb076f.js.map +0 -1
  76. package/test-site/eslint.config.js +0 -12
  77. package/test-site/package-lock.json +0 -19226
  78. package/test-site/package.json +0 -29
  79. package/test-site/public/index.html +0 -10
  80. package/test-site/site.config.build.tsx +0 -27
  81. package/test-site/site.config.dev.tsx +0 -27
  82. package/test-site/src/authenticated-page/AuthenticatedPage.tsx +0 -18
  83. package/test-site/src/authenticated-page/i18n/index.ts +0 -27
  84. package/test-site/src/authenticated-page/index.tsx +0 -28
  85. package/test-site/src/example-page/ExamplePage.tsx +0 -79
  86. package/test-site/src/example-page/Image.tsx +0 -11
  87. package/test-site/src/example-page/ParagonPreview.jsx +0 -66
  88. package/test-site/src/example-page/apple.jpg +0 -0
  89. package/test-site/src/example-page/apple.svg +0 -1
  90. package/test-site/src/example-page/index.ts +0 -16
  91. package/test-site/src/i18n/README.md +0 -3
  92. package/test-site/src/i18n/messages/frontend-app-sample/ar.json +0 -4
  93. package/test-site/src/i18n/messages/frontend-app-sample/eo.json +0 -1
  94. package/test-site/src/i18n/messages/frontend-app-sample/es_419.json +0 -4
  95. package/test-site/src/i18n/messages/frontend-component-emptylangs/ar.json +0 -1
  96. package/test-site/src/i18n/messages/frontend-component-singlelang/ar.json +0 -3
  97. package/test-site/src/iframe-widget/IframeWidget.tsx +0 -14
  98. package/test-site/src/iframe-widget/index.ts +0 -16
  99. package/test-site/src/index.tsx +0 -3
  100. package/test-site/src/messages.js +0 -11
  101. package/test-site/src/site.scss +0 -11
  102. package/test-site/tsconfig.json +0 -14
  103. package/tools/babel/babel.config.js +0 -27
  104. package/tools/babel.config.js +0 -3
  105. package/tools/cli/README.md +0 -29
  106. package/tools/cli/commands/pack.ts +0 -9
  107. package/tools/cli/commands/release.ts +0 -27
  108. package/tools/cli/commands/serve.ts +0 -43
  109. package/tools/cli/intl-imports.ts +0 -274
  110. package/tools/cli/openedx.ts +0 -101
  111. package/tools/cli/transifex-utils.ts +0 -75
  112. package/tools/cli/utils/ensureConfigFilenameOption.ts +0 -40
  113. package/tools/cli/utils/formatter.ts +0 -10
  114. package/tools/cli/utils/getResolvedConfigPath.ts +0 -23
  115. package/tools/cli/utils/prettyPrintTitle.ts +0 -15
  116. package/tools/cli/utils/printUsage.ts +0 -53
  117. package/tools/config-helpers/createConfig.ts +0 -8
  118. package/tools/config-helpers/createLintConfig.ts +0 -14
  119. package/tools/config-helpers/getBaseConfig.ts +0 -11
  120. package/tools/defaultConfigPaths.ts +0 -30
  121. package/tools/dist/cli/commands/pack.js +0 -14
  122. package/tools/dist/cli/commands/release.js +0 -28
  123. package/tools/eslint/base.eslint.config.js +0 -124
  124. package/tools/eslint/modules.d.ts +0 -5
  125. package/tools/eslint.config.js +0 -15
  126. package/tools/index.ts +0 -3
  127. package/tools/jest/jest.config.js +0 -30
  128. package/tools/jest.config.js +0 -19
  129. package/tools/tsconfig.json +0 -24
  130. package/tools/types.ts +0 -21
  131. package/tools/typescript/tsconfig.json +0 -32
  132. package/tools/webpack/common-config/README.md +0 -15
  133. package/tools/webpack/common-config/all/getCodeRules.ts +0 -51
  134. package/tools/webpack/common-config/all/getFileLoaderRules.ts +0 -23
  135. package/tools/webpack/common-config/all/getIgnoreWarnings.ts +0 -13
  136. package/tools/webpack/common-config/all/getImageMinimizer.ts +0 -26
  137. package/tools/webpack/common-config/all/getStylesheetRule.ts +0 -111
  138. package/tools/webpack/common-config/dev/getDevServer.ts +0 -35
  139. package/tools/webpack/common-config/index.ts +0 -6
  140. package/tools/webpack/common-config/site/getHtmlWebpackPlugin.ts +0 -11
  141. package/tools/webpack/modules.d.ts +0 -6
  142. package/tools/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.ts +0 -102
  143. package/tools/webpack/plugins/html-webpack-new-relic-plugin/LICENSE +0 -21
  144. package/tools/webpack/plugins/html-webpack-new-relic-plugin/README.md +0 -7
  145. package/tools/webpack/plugins/html-webpack-new-relic-plugin/index.js +0 -3
  146. package/tools/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +0 -1
  147. package/tools/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.ts +0 -134
  148. package/tools/webpack/plugins/paragon-webpack-plugin/index.ts +0 -3
  149. package/tools/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.ts +0 -71
  150. package/tools/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.ts +0 -72
  151. package/tools/webpack/plugins/paragon-webpack-plugin/utils/index.ts +0 -6
  152. package/tools/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.ts +0 -131
  153. package/tools/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.ts +0 -144
  154. package/tools/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.ts +0 -106
  155. package/tools/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.ts +0 -54
  156. package/tools/webpack/types.ts +0 -69
  157. package/tools/webpack/utils/getLocalAliases.ts +0 -65
  158. package/tools/webpack/utils/getPublicPath.ts +0 -3
  159. package/tools/webpack/utils/getResolvedSiteConfigPath.ts +0 -28
  160. package/tools/webpack/utils/paragonUtils.ts +0 -152
  161. package/tools/webpack/webpack.config.build.ts +0 -93
  162. package/tools/webpack/webpack.config.dev.shell.ts +0 -122
  163. package/tools/webpack/webpack.config.dev.ts +0 -90
  164. package/tsconfig.json +0 -23
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ // Tests for the intl-imports.js command line.
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const path_1 = __importDefault(require("path"));
8
+ const intl_imports_1 = require("./intl-imports");
9
+ const sampleAppDirectory = path_1.default.join(__dirname, '../../test-site');
10
+ // History for `process.stdout.write` mock calls.
11
+ const logHistory = {
12
+ log: [],
13
+ latest: '',
14
+ };
15
+ // History for `fs.writeFileSync` mock calls.
16
+ const writeFileHistory = {
17
+ log: [],
18
+ latest: null,
19
+ };
20
+ // Mock for process.stdout.write
21
+ const log = (text) => {
22
+ logHistory.latest = text;
23
+ logHistory.log.push(text);
24
+ };
25
+ // Mock for fs.writeFileSync
26
+ const writeFileSync = (filename, content) => {
27
+ const entry = { filename, content };
28
+ writeFileHistory.latest = entry;
29
+ writeFileHistory.log.push(entry);
30
+ };
31
+ // Main with mocked output
32
+ const main = (...directories) => (0, intl_imports_1.main)({
33
+ directories,
34
+ log,
35
+ writeFileSync,
36
+ pwd: sampleAppDirectory,
37
+ });
38
+ // Clean up mock histories
39
+ afterEach(() => {
40
+ logHistory.log = [];
41
+ logHistory.latest = null;
42
+ writeFileHistory.log = [];
43
+ writeFileHistory.latest = null;
44
+ });
45
+ describe('help document', () => {
46
+ it('should print help for --help', () => {
47
+ main('--help');
48
+ expect(logHistory.latest).toMatch('Script to generate the src/i18n/index.js');
49
+ });
50
+ it('should print help for -h', () => {
51
+ main('-h');
52
+ expect(logHistory.latest).toMatch('Script to generate the src/i18n/index.js');
53
+ });
54
+ });
55
+ describe('error validation', () => {
56
+ it('expects a list of directories', () => {
57
+ main();
58
+ expect(logHistory.log.join('\n')).toMatch('Script to generate the src/i18n/index.js'); // Print help error
59
+ expect(logHistory.latest).toMatch('Error: A list of directories is required'); // Print error message
60
+ });
61
+ it('expects a directory with a relative path of "src/i18n"', () => {
62
+ (0, intl_imports_1.main)({
63
+ directories: ['frontend-app-example'],
64
+ log,
65
+ writeFileSync,
66
+ pwd: path_1.default.join(__dirname), // __dirname === `scripts` which has no sub-dir `src/i18n`
67
+ });
68
+ expect(logHistory.log.join('\n')).toMatch('Script to generate the src/i18n/index.js'); // Print help on error
69
+ expect(logHistory.latest).toMatch('Error: src/i18n directory was not found.'); // Print error message
70
+ });
71
+ });
72
+ describe('generated files', () => {
73
+ it('writes a correct src/i18n/index.js file', () => {
74
+ main('frontend-component-singlelang', 'frontend-component-nolangs', 'frontend-component-emptylangs', 'frontend-app-sample');
75
+ const mainFileActualContent = writeFileHistory.log.find((file) => {
76
+ return file.filename.endsWith('src/i18n/index.js');
77
+ })?.content;
78
+ const mainFileExpectedContent = `// This file is generated by the openedx/frontend-base's "intl-import.js" script.
79
+ //
80
+ // Refer to the i18n documents in https://docs.openedx.org/en/latest/developers/references/i18n.html to update
81
+ // the file and use the Micro-frontend i18n pattern in new repositories.
82
+ //
83
+
84
+ import messagesFromFrontendComponentSinglelang from './messages/frontend-component-singlelang';
85
+ // Skipped import due to missing 'frontend-component-nolangs/index.js' likely due to empty translations..
86
+ // Skipped import due to missing 'frontend-component-emptylangs/index.js' likely due to empty translations..
87
+ import messagesFromFrontendAppSample from './messages/frontend-app-sample';
88
+
89
+ export default [
90
+ messagesFromFrontendComponentSinglelang,
91
+ messagesFromFrontendAppSample,
92
+ ];
93
+ `;
94
+ expect(mainFileActualContent).toEqual(mainFileExpectedContent);
95
+ });
96
+ it('writes a correct frontend-component-singlelang/index.js file', () => {
97
+ main('frontend-component-singlelang', 'frontend-component-nolangs', 'frontend-component-emptylangs', 'frontend-app-sample');
98
+ const mainFileActualContent = writeFileHistory.log.find(file => file.filename.endsWith('frontend-component-singlelang/index.js'))?.content;
99
+ const singleLangExpectedContent = `// This file is generated by the openedx/frontend-base's "intl-import.js" script.
100
+ //
101
+ // Refer to the i18n documents in https://docs.openedx.org/en/latest/developers/references/i18n.html to update
102
+ // the file and use the Micro-frontend i18n pattern in new repositories.
103
+ //
104
+
105
+ import messagesOfArLanguage from './ar.json';
106
+
107
+ export default {
108
+ 'ar': messagesOfArLanguage,
109
+ };
110
+ `;
111
+ expect(mainFileActualContent).toEqual(singleLangExpectedContent);
112
+ });
113
+ it('writes a correct frontend-app-sample/index.js file', () => {
114
+ main('frontend-component-singlelang', 'frontend-component-nolangs', 'frontend-component-emptylangs', 'frontend-app-sample');
115
+ const mainFileActualContent = writeFileHistory.log.find(file => file.filename.endsWith('frontend-app-sample/index.js'))?.content;
116
+ const singleLangExpectedContent = `// This file is generated by the openedx/frontend-base's "intl-import.js" script.
117
+ //
118
+ // Refer to the i18n documents in https://docs.openedx.org/en/latest/developers/references/i18n.html to update
119
+ // the file and use the Micro-frontend i18n pattern in new repositories.
120
+ //
121
+
122
+ import messagesOfArLanguage from './ar.json';
123
+ // Note: Skipped empty 'eo.json' messages file.
124
+ import messagesOfEs419Language from './es_419.json';
125
+
126
+ export default {
127
+ 'ar': messagesOfArLanguage,
128
+ 'es-419': messagesOfEs419Language,
129
+ };
130
+ `;
131
+ expect(mainFileActualContent).toEqual(singleLangExpectedContent);
132
+ });
133
+ });
134
+ describe('list of generated index.js files', () => {
135
+ it('writes only non-empty languages in addition to the main file', () => {
136
+ main('frontend-component-singlelang', 'frontend-component-nolangs', 'frontend-component-emptylangs', 'frontend-app-sample');
137
+ const writtenFiles = writeFileHistory.log
138
+ .map(file => file.filename)
139
+ .map(file => path_1.default.relative(sampleAppDirectory, file));
140
+ expect(writtenFiles).toEqual([
141
+ 'src/i18n/messages/frontend-component-singlelang/index.js',
142
+ 'src/i18n/messages/frontend-app-sample/index.js',
143
+ 'src/i18n/index.js',
144
+ ]);
145
+ });
146
+ });
@@ -8,8 +8,6 @@ const chalk_1 = __importDefault(require("chalk"));
8
8
  const fs_1 = require("fs");
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const types_1 = require("../types");
11
- const pack_1 = __importDefault(require("./commands/pack"));
12
- const release_1 = __importDefault(require("./commands/release"));
13
11
  const ensureConfigFilenameOption_1 = require("./utils/ensureConfigFilenameOption");
14
12
  const prettyPrintTitle_1 = __importDefault(require("./utils/prettyPrintTitle"));
15
13
  const printUsage_1 = __importDefault(require("./utils/printUsage"));
@@ -26,18 +24,6 @@ else if ((0, fs_1.existsSync)(path_1.default.resolve(__dirname, '../../../packag
26
24
  }
27
25
  (0, prettyPrintTitle_1.default)(`Open edX CLI v${version}`);
28
26
  switch (commandName) {
29
- case types_1.CommandTypes.RELEASE:
30
- (0, release_1.default)();
31
- break;
32
- case types_1.CommandTypes.PACK:
33
- if (process.argv[2] === undefined) {
34
- console.log(chalk_1.default.red(`${chalk_1.default.bold.red(commandName)} command usage: specify a peer folder where the command should install the package:
35
-
36
- npm run pack my-project`));
37
- process.exit(1);
38
- }
39
- (0, pack_1.default)();
40
- break;
41
27
  case types_1.CommandTypes.LINT:
42
28
  (0, ensureConfigFilenameOption_1.ensureConfigFilenameOption)(types_1.ConfigTypes.LINT, ['-c', '--config']);
43
29
  require('.bin/eslint');
@@ -78,7 +64,7 @@ switch (commandName) {
78
64
  srcFoldersString = `{${srcFoldersString}}`;
79
65
  }
80
66
  process.argv = process.argv.concat([
81
- '--format', 'node_modules/@openedx/frontend-base/dist/tools/cli/utils/formatter.js',
67
+ '--format', 'node_modules/@openedx/frontend-base/tools/dist/cli/utils/formatter.js',
82
68
  '--ignore', `${srcFoldersString}/**/*.json`,
83
69
  '--ignore', `${srcFoldersString}/**/*.d.ts`,
84
70
  '--out-file', './temp/formatjs/Default.messages.json',
@@ -11,15 +11,6 @@ function printUsage() {
11
11
  console.log('openedx <command> <options>\n');
12
12
  console.groupEnd();
13
13
  console.log('Commands:\n');
14
- console.group();
15
- console.log(`${chalk_1.default.bold('release')}\n`);
16
- console.group();
17
- console.log(`Compile source code for release as a library. Compiled code is put into the dist folder.\n`);
18
- console.groupEnd();
19
- console.log(`${chalk_1.default.bold('pack')} <peer folder>\n`);
20
- console.group();
21
- console.log(`Package the dist folder as an NPM-compatible .tgz file suitable for use with npm install, then install it in the specified peer folder. The folder is assumed to be a peer of this repository, do not include a path.\n`);
22
- console.groupEnd();
23
14
  console.log(`${chalk_1.default.bold('lint')} <eslint options>\n`);
24
15
  console.group();
25
16
  console.log(`Runs ESLint on the source code. Requires an ${chalk_1.default.bold('eslint.config.js')} file.\n`);
@@ -12,8 +12,6 @@ var ConfigTypes;
12
12
  })(ConfigTypes || (exports.ConfigTypes = ConfigTypes = {}));
13
13
  var CommandTypes;
14
14
  (function (CommandTypes) {
15
- CommandTypes["RELEASE"] = "release";
16
- CommandTypes["PACK"] = "pack";
17
15
  CommandTypes["LINT"] = "lint";
18
16
  CommandTypes["TEST"] = "test";
19
17
  CommandTypes["BUILD"] = "build";
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ const html_webpack_plugin_1 = __importDefault(require("html-webpack-plugin"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const webpack_1 = __importDefault(require("webpack"));
10
+ const HtmlWebpackNewRelicPlugin_1 = __importDefault(require("../HtmlWebpackNewRelicPlugin"));
11
+ const OUTPUT_DIR = path_1.default.join(__dirname, './dist');
12
+ describe('HtmlWebpackNewRelicPlugin', () => {
13
+ const testPluginOptions = {
14
+ accountID: '121212',
15
+ agentID: '343434',
16
+ trustKey: '565656',
17
+ licenseKey: '123456',
18
+ applicationID: '654321',
19
+ };
20
+ afterEach(() => {
21
+ if (fs_1.default.existsSync(OUTPUT_DIR)) {
22
+ fs_1.default.rmSync(OUTPUT_DIR, { recursive: true, force: true });
23
+ }
24
+ });
25
+ it('should append new relic script to body', done => {
26
+ (0, webpack_1.default)({
27
+ entry: path_1.default.resolve(__dirname, 'fixtures', 'entry.js'),
28
+ output: {
29
+ path: path_1.default.resolve(__dirname, './dist'),
30
+ },
31
+ plugins: [
32
+ new html_webpack_plugin_1.default(),
33
+ new HtmlWebpackNewRelicPlugin_1.default(testPluginOptions),
34
+ ],
35
+ }, (err) => {
36
+ const htmlFile = path_1.default.resolve(OUTPUT_DIR, 'index.html');
37
+ expect(err).toBeNull();
38
+ expect(fs_1.default.existsSync(htmlFile)).toBe(true);
39
+ const file = fs_1.default.readFileSync(path_1.default.resolve(OUTPUT_DIR, htmlFile), { encoding: 'utf-8' }, (error, data) => data.toString());
40
+ Object.entries(testPluginOptions).forEach(([optionName, optionValue]) => {
41
+ expect(file.indexOf(`${optionName}:"${optionValue}"`)).toBeGreaterThan(-1);
42
+ });
43
+ done();
44
+ });
45
+ });
46
+ describe('when its missing configuration variables', () => {
47
+ function testMissingOption(missingOptionName) {
48
+ it(`should throw error if ${missingOptionName} is missing`, done => {
49
+ const compiler = (0, webpack_1.default)({
50
+ entry: path_1.default.resolve(__dirname, 'fixtures', 'entry.js'),
51
+ output: {
52
+ path: path_1.default.resolve(__dirname, '../dist'),
53
+ },
54
+ plugins: [new html_webpack_plugin_1.default()],
55
+ });
56
+ const optionsMissingOne = { ...testPluginOptions };
57
+ delete optionsMissingOne[missingOptionName];
58
+ expect(() => compiler.options.plugins.push(new HtmlWebpackNewRelicPlugin_1.default(optionsMissingOne))).toThrow(`${missingOptionName} argument is required`);
59
+ done();
60
+ });
61
+ }
62
+ Object.keys(testPluginOptions).forEach((key) => {
63
+ testMissingOption(key);
64
+ });
65
+ });
66
+ });
package/types.ts CHANGED
@@ -13,7 +13,7 @@ export interface ExternalRoute {
13
13
  export type RoleRouteObject = RouteObject & {
14
14
  handle?: {
15
15
  /**
16
- * A route role is used to identify a route that fulfills a particular role in the site, such as "login", "learnerHome", or "profile".
16
+ * A route role is used to identify a route that fulfills a particular role in the site.
17
17
  */
18
18
  role?: string,
19
19
  },
package/eslint.config.js DELETED
@@ -1,18 +0,0 @@
1
- // @ts-check
2
-
3
- const tseslint = require('typescript-eslint');
4
- const eslintConfig = require('./tools/eslint/base.eslint.config.js');
5
-
6
- module.exports = tseslint.config(
7
- {
8
- extends: eslintConfig,
9
- },
10
- {
11
- ignores: [
12
- 'tools/*',
13
- 'test-site/*',
14
- 'config/*',
15
- 'docs/*',
16
- ],
17
- },
18
- );
@@ -1,8 +0,0 @@
1
- declare module 'site.config' {
2
- export default SiteConfig;
3
- }
4
-
5
- declare module '*.svg' {
6
- const content: string;
7
- export default content;
8
- }
package/jest.config.js DELETED
@@ -1,7 +0,0 @@
1
- module.exports = {
2
- projects: [
3
- 'tools',
4
- 'runtime',
5
- 'shell',
6
- ],
7
- };
Binary file
@@ -1,15 +0,0 @@
1
- /// <reference types="@openedx/frontend-base" />
2
-
3
- declare module 'site.config' {
4
- export default SiteConfig;
5
- }
6
-
7
- declare module '*.svg' {
8
- const content: string;
9
- export default content;
10
- }
11
-
12
- declare module '*.jpg' {
13
- const content: string;
14
- export default content;
15
- }
@@ -1,2 +0,0 @@
1
- "use strict";(self.webpackChunktest_site=self.webpackChunktest_site||[]).push([[176],{2176:(e,r,s)=>{s.r(r),s.d(r,{default:()=>y});var t=s(7517),n=s(5029),i=s(8083),l=s(574),a=s(2800),c=s(5601),o=s(3440),d=s(8313),h=s(3273);const p=(0,s(7050).YK)({"test-site.message":{id:"test-site.message",defaultMessage:"This message proves that i18n is working."}});const g=e=>{var{alt:r}=e,s=function(e,r){var s={};for(var t in e)Object.prototype.hasOwnProperty.call(e,t)&&r.indexOf(t)<0&&(s[t]=e[t]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(t=Object.getOwnPropertySymbols(e);n<t.length;n++)r.indexOf(t[n])<0&&Object.prototype.propertyIsEnumerable.call(e,t[n])&&(s[t[n]]=e[t[n]])}return s}(e,["alt"]);return(0,t.jsx)("img",Object.assign({alt:r},s))};var x=s(2907),j=s.n(x),m=s(7141),f=s.n(m);const u=(0,d.forwardRef)(((e,r)=>{let{direction:s,gap:t,reversed:n,children:i,className:l}=e,a=function(e,r){var s={};for(var t in e)Object.prototype.hasOwnProperty.call(e,t)&&r.indexOf(t)<0&&(s[t]=e[t]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(t=Object.getOwnPropertySymbols(e);n<t.length;n++)r.indexOf(t[n])<0&&Object.prototype.propertyIsEnumerable.call(e,t[n])&&(s[t[n]]=e[t[n]])}return s}(e,["direction","gap","reversed","children","className"]);return d.createElement("div",Object.assign({ref:r,className:f()("horizontal"===s?"pgn__hstack":"pgn__vstack",t?`pgn__stack-gap--${t}`:"",n?"pgn__stack-reversed":"",l)},a),i)}));u.propTypes={children:j().node.isRequired,direction:j().oneOf(["horizontal","vertical"]),gap:j().number,reversed:j().bool,className:j().string},u.defaultProps={direction:"vertical",gap:0,className:void 0,reversed:!1};const b=u;var v=s(4152);const N=()=>{var e,r;return PARAGON_THEME?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("h2",{children:"Paragon"}),(0,t.jsxs)(b,{gap:4.5,children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h3",{children:"Component preview"}),(0,t.jsx)("div",{className:"px-3 py-2 bg-light-200",children:(0,t.jsx)(v.Ay,{children:"Hello world"})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("h3",{children:"Exposed theme CSS files"}),(0,t.jsx)("p",{children:(0,t.jsxs)("em",{children:["Note: Depending on the versions of ",(0,t.jsx)("code",{children:"@openedx/paragon"})," and/or ",(0,t.jsx)("code",{children:"@edx/brand"})," installed, it is expected that no exposed theme CSS assets be listed here."]})}),(0,t.jsxs)("ul",{className:"mb-0",children:[PARAGON_THEME.paragon.themeUrls.core.fileName&&(0,t.jsx)("li",{children:(0,t.jsx)("a",{href:`/${PARAGON_THEME.paragon.themeUrls.core.fileName}`,target:"_blank",rel:"noopener noreferrer",children:PARAGON_THEME.paragon.themeUrls.core.fileName})}),(null===(e=PARAGON_THEME.paragon.themeUrls.variants.light)||void 0===e?void 0:e.fileName)&&(0,t.jsx)("li",{children:(0,t.jsx)("a",{href:`/${PARAGON_THEME.paragon.themeUrls.variants.light.fileName}`,target:"_blank",rel:"noopener noreferrer",children:PARAGON_THEME.paragon.themeUrls.variants.light.fileName})}),PARAGON_THEME.brand.themeUrls.core.fileName&&(0,t.jsx)("li",{children:(0,t.jsx)("a",{href:`/${PARAGON_THEME.brand.themeUrls.core.fileName}`,target:"_blank",rel:"noopener noreferrer",children:PARAGON_THEME.brand.themeUrls.core.fileName})}),(null===(r=PARAGON_THEME.brand.themeUrls.variants.light)||void 0===r?void 0:r.fileName)&&(0,t.jsx)("li",{children:(0,t.jsx)("a",{href:`/${PARAGON_THEME.brand.themeUrls.variants.light.fileName}`,target:"_blank",rel:"noopener noreferrer",children:PARAGON_THEME.brand.themeUrls.variants.light.fileName})})]})]}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("h3",{children:["Contents of ",(0,t.jsx)("code",{children:"PARAGON_THEME"})," global variable"]}),(0,t.jsx)("pre",{children:JSON.stringify(PARAGON_THEME,null,2)})]})]})]}):(0,t.jsxs)("p",{children:["Missing ",(0,t.jsx)("code",{children:"PARAGON_THEME"})," global variable. Depending on configuration, this may be OK."]})},A=s.p+"74e025d3fe9a7b7f8503054e2563b353.jpg",O=s.p+"cb28cdb1468c915e27e5cec9af64f22f.svg";function E(e){return e?"✅":"❌"}function y(){const e=(0,n.zn)(),r=(0,n.QR)(),s=(0,i.A)();return(0,d.useEffect)((()=>{(0,l.fH)("The example page can log info, which means logging is configured correctly.")}),[]),(0,t.jsxs)(o.A,{children:[(0,t.jsxs)("h1",{children:[e.siteName," test page"]}),(0,t.jsx)("h2",{children:"Links"}),(0,t.jsxs)("p",{children:["Visit ",(0,t.jsx)(h.N_,{to:"/authenticated",children:"authenticated page"}),"."]}),(0,t.jsxs)("p",{children:["Visit ",(0,t.jsx)(h.N_,{to:"/error",children:"error page"}),"."]}),(0,t.jsx)("h2",{children:"Context Config Test"}),(0,t.jsxs)("p",{children:["Is context.config equal to getSiteConfig()? ",E(e===(0,a.Q2)())]}),(0,t.jsxs)("p",{children:["Is context.authenticatedUser equal to getAuthenticatedUser()? ",E(r===(0,c.vD)())]}),(0,t.jsx)("h2",{children:"SCSS parsing tests"}),(0,t.jsxs)("p",{children:[(0,t.jsx)("span",{className:"red-text",children:'"The Apples"'})," should be red (",(0,t.jsx)("code",{children:"color: red;"})," via ",(0,t.jsx)("code",{children:".red-text"})," CSS class in SCSS stylesheet)"]}),(0,t.jsx)("h2",{children:"TSX parsing tests"}),(0,t.jsx)(g,{src:O,alt:"apple.svg displayed in Image.tsx",style:{width:"10rem"}}),(0,t.jsx)("h2",{children:"SVG import test"}),(0,t.jsx)("img",{src:O,alt:"apple.svg displayed in <img> tag",style:{width:"10rem"}}),(0,t.jsx)("h2",{children:"JPG import test"}),(0,t.jsx)("p",{children:(0,t.jsx)("img",{src:A,alt:"apple.jpg displayed in <img> tag",style:{width:"10rem"}})}),(0,t.jsx)("p",{children:"Photo by Louis Hansel @shotsoflouis on Unsplash"}),(0,t.jsx)("h2",{children:"i18n formatMessage test"}),(0,t.jsx)("p",{children:s.formatMessage(p["test-site.message"])}),(0,t.jsx)("h2",{children:"Authenticated User Test"}),null!==r?(0,t.jsxs)("div",{children:[(0,t.jsxs)("p",{children:["Authenticated Username: ",(0,t.jsx)("strong",{children:r.username})]}),(0,t.jsxs)("p",{children:["Authenticated user's name:",(0,t.jsx)("strong",{children:r.username}),"(Only available if user account has been fetched)"]})]}):(0,t.jsxs)("p",{children:["Unauthenticated ",E(null===r)]}),(0,t.jsx)("h2",{children:"Right-to-left language handling tests"}),(0,t.jsx)("p",{className:"text-align-right",children:"I'm aligned right, but left in RTL."}),(0,t.jsx)(N,{})]})}}}]);
2
- //# sourceMappingURL=176.436443549ebb858db483.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"176.436443549ebb858db483.js","mappings":"gOAEA,MAQA,GARiB,E,QAAA,IAAe,CAC9B,oBAAqB,CAAF,qFCKrB,MAEA,EAFe,I,IAAA,IAAEA,GAAG,EAAKC,E,yUAAI,GAAd,SAAiC,qCAAKD,IAAKA,GAASC,K,0CCJnE,MAKMC,GAAQC,EAAAA,EAAAA,aAAW,CAAAC,EAOtBC,KAAG,IAPoB,UACxBC,EAAS,IACTC,EAAG,SACHC,EAAQ,SACRC,EAAQ,UACRC,GAEDN,EADIH,E,yUAAAA,CACJG,EAPyB,uDAOzB,OACCO,EAAAA,cAAA,qBACEN,IAAKA,EACLK,UAAWE,IACK,eAAdN,EAA6B,cAAgB,cAC7CC,EAAM,mBAAmBA,IAAQ,GACjCC,EAAW,sBAAwB,GACnCE,IAEET,GAEHQ,MAILP,EAAMW,UAAY,CAEhBJ,SAAUK,IAAAA,KAAeC,WAEzBT,UAAWQ,IAAAA,MA/Bc,CACzB,aACA,aAoCAP,IAAKO,IAAAA,OAELN,SAAUM,IAAAA,KAEVJ,UAAWI,IAAAA,QAGbZ,EAAMc,aAAe,CACnBV,UAAW,WACXC,IAAK,EACLG,eAAWO,EACXT,UAAU,GAGZ,U,cCtDA,MA+DA,EA/DuB,K,QACrB,OAAKU,eAIH,iCACE,qCAEA,UAAC,EAAK,CAACX,IAAK,IAAG,WACb,4BACE,+CACA,gBAAKG,UAAU,yBAAwB,UACrC,SAACS,EAAA,GAAM,gCAGX,4BACE,qDACA,wBACE,iEACqC,+CAA6B,YAAQ,yCAAuB,oFAInG,gBAAIT,UAAU,OAAM,UACjBQ,cAAcE,QAAQC,UAAUC,KAAKC,WACpC,yBACE,cAAGC,KAAM,IAAIN,cAAcE,QAAQC,UAAUC,KAAKC,WAAYE,OAAO,SAASC,IAAI,sBAAqB,SACpGR,cAAcE,QAAQC,UAAUC,KAAKC,cAIG,QAA9C,EAAAL,cAAcE,QAAQC,UAAUM,SAASC,aAAK,eAAEL,YAC/C,yBACE,cAAGC,KAAM,IAAIN,cAAcE,QAAQC,UAAUM,SAASC,MAAML,WAAYE,OAAO,SAASC,IAAI,sBAAqB,SAC9GR,cAAcE,QAAQC,UAAUM,SAASC,MAAML,aAIrDL,cAAcW,MAAMR,UAAUC,KAAKC,WAClC,yBACE,cAAGC,KAAM,IAAIN,cAAcW,MAAMR,UAAUC,KAAKC,WAAYE,OAAO,SAASC,IAAI,sBAAqB,SAClGR,cAAcW,MAAMR,UAAUC,KAAKC,cAIG,QAA5C,EAAAL,cAAcW,MAAMR,UAAUM,SAASC,aAAK,eAAEL,YAC7C,yBACE,cAAGC,KAAM,IAAIN,cAAcW,MAAMR,UAAUM,SAASC,MAAML,WAAYE,OAAO,SAASC,IAAI,sBAAqB,SAC5GR,cAAcW,MAAMR,UAAUM,SAASC,MAAML,oBAMxD,4BACE,0CAAgB,4CAA0B,uBAC1C,yBAAMO,KAAKC,UAAUb,cAAe,KAAM,eAtDzC,qCAAW,4CAA0B,oECJhD,EAAe,IAA0B,uCCAzC,EAAe,IAA0B,uCCiBzC,SAASc,EAAgBC,GACvB,OAAOA,EAAQ,IAAM,GACvB,CAEe,SAASC,IACtB,MAAMC,GAAS,UACTC,GAAoB,UAEpBC,GAAO,EAAAC,EAAA,KAMb,OAJA,IAAAC,YAAU,MACR,QAAQ,iFACP,KAGD,UAACC,EAAA,EAAS,YACR,0BAAKL,EAAOM,SAAQ,iBAEpB,mCACA,mCAAS,SAAC,KAAI,CAACC,GAAG,iBAAgB,gCAA0B,QAC5D,mCAAS,SAAC,KAAI,CAACA,GAAG,SAAQ,wBAAkB,QAE5C,iDACA,wEAAgDV,EAAgBG,KAAW,eAC3E,0FAAkEH,EAAgBI,KAAsB,eAExG,gDACA,0BAAG,iBAAM1B,UAAU,WAAU,0BAA8B,oBAAgB,0CAAwB,SAAK,wCAAsB,qCAE9H,+CACA,SAAC,EAAK,CAACiC,IAAK,EAAU3C,IAAI,mCAAmC4C,MAAO,CAAEC,MAAO,YAE7E,6CACA,gBAAKF,IAAK,EAAU3C,IAAI,mCAAmC4C,MAAO,CAAEC,MAAO,YAE3E,6CACA,wBAAG,gBAAKF,IAAKG,EAAU9C,IAAI,mCAAmC4C,MAAO,CAAEC,MAAO,cAC9E,4EAEA,qDACA,uBAAIR,EAAKU,cAAc,EAAS,yBAEhC,oDACuB,OAAtBX,GACC,4BACE,qDAA2B,4BAASA,EAAkBY,eACtD,uDAEE,4BAASZ,EAAkBY,WAAkB,2DAKjD,4CAAoBhB,EAAsC,OAAtBI,OAGtC,mEACA,cAAG1B,UAAU,mBAAkB,kDAC/B,SAAC,EAAc,MAGrB,C","sources":["webpack://test-site/./src/messages.js","webpack://test-site/./src/example-page/Image.tsx","webpack://test-site/./node_modules/@openedx/paragon/src/Stack/index.jsx","webpack://test-site/./src/example-page/ParagonPreview.jsx","webpack://test-site/./src/example-page/apple.jpg","webpack://test-site/./src/example-page/apple.svg","webpack://test-site/./src/example-page/ExamplePage.tsx"],"sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n 'test-site.message': {\n id: 'test-site.message',\n defaultMessage: 'This message proves that i18n is working.',\n description: 'A message that proves that internationalization is working.',\n },\n});\n\nexport default messages;\n","import { CSSProperties } from 'react';\n\ninterface ImageProps {\n src: string,\n alt?: string,\n style?: CSSProperties,\n}\n\nconst Image = ({ alt, ...rest }: ImageProps) => <img alt={alt} {...rest} />;\n\nexport default Image;\n","import React, { forwardRef } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\n\nconst DIRECTION_VARIANTS = [\n 'horizontal',\n 'vertical',\n];\n\nconst Stack = forwardRef(({\n direction,\n gap,\n reversed,\n children,\n className,\n ...rest\n}, ref) => (\n <div\n ref={ref}\n className={classNames(\n direction === 'horizontal' ? 'pgn__hstack' : 'pgn__vstack',\n gap ? `pgn__stack-gap--${gap}` : '',\n reversed ? 'pgn__stack-reversed' : '',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n));\n\nStack.propTypes = {\n /** Specifies the content of the `Stack`. */\n children: PropTypes.node.isRequired,\n /** Specifies direction of the children blocks (column/row). */\n direction: PropTypes.oneOf(DIRECTION_VARIANTS),\n /**\n * Specifies inner space between children blocks.\n *\n * Valid values are based on `the spacing classes`:\n * `0, 0.5, ... 6`.\n */\n gap: PropTypes.number,\n /** Specifies the order of the children. */\n reversed: PropTypes.bool,\n /** Specifies an additional `className` to add to the base element. */\n className: PropTypes.string,\n};\n\nStack.defaultProps = {\n direction: 'vertical',\n gap: 0,\n className: undefined,\n reversed: false,\n};\n\nexport default Stack;\n","import { Button, Stack } from '@openedx/paragon';\n\nconst ParagonPreview = () => {\n if (!PARAGON_THEME) {\n return <p>Missing <code>PARAGON_THEME</code> global variable. Depending on configuration, this may be OK.</p>;\n }\n return (\n <>\n <h2>Paragon</h2>\n\n <Stack gap={4.5}>\n <div>\n <h3>Component preview</h3>\n <div className=\"px-3 py-2 bg-light-200\">\n <Button>Hello world</Button>\n </div>\n </div>\n <div>\n <h3>Exposed theme CSS files</h3>\n <p>\n <em>\n Note: Depending on the versions of <code>@openedx/paragon</code> and/or <code>@edx/brand</code> installed,\n it is expected that no exposed theme CSS assets be listed here.\n </em>\n </p>\n <ul className=\"mb-0\">\n {PARAGON_THEME.paragon.themeUrls.core.fileName && (\n <li>\n <a href={`/${PARAGON_THEME.paragon.themeUrls.core.fileName}`} target=\"_blank\" rel=\"noopener noreferrer\">\n {PARAGON_THEME.paragon.themeUrls.core.fileName}\n </a>\n </li>\n )}\n {PARAGON_THEME.paragon.themeUrls.variants.light?.fileName && (\n <li>\n <a href={`/${PARAGON_THEME.paragon.themeUrls.variants.light.fileName}`} target=\"_blank\" rel=\"noopener noreferrer\">\n {PARAGON_THEME.paragon.themeUrls.variants.light.fileName}\n </a>\n </li>\n )}\n {PARAGON_THEME.brand.themeUrls.core.fileName && (\n <li>\n <a href={`/${PARAGON_THEME.brand.themeUrls.core.fileName}`} target=\"_blank\" rel=\"noopener noreferrer\">\n {PARAGON_THEME.brand.themeUrls.core.fileName}\n </a>\n </li>\n )}\n {PARAGON_THEME.brand.themeUrls.variants.light?.fileName && (\n <li>\n <a href={`/${PARAGON_THEME.brand.themeUrls.variants.light.fileName}`} target=\"_blank\" rel=\"noopener noreferrer\">\n {PARAGON_THEME.brand.themeUrls.variants.light.fileName}\n </a>\n </li>\n )}\n </ul>\n </div>\n <div>\n <h3>Contents of <code>PARAGON_THEME</code> global variable</h3>\n <pre>{JSON.stringify(PARAGON_THEME, null, 2)}</pre>\n </div>\n </Stack>\n </>\n );\n};\n\nexport default ParagonPreview;\n","export default __webpack_public_path__ + \"74e025d3fe9a7b7f8503054e2563b353.jpg\";","export default __webpack_public_path__ + \"cb28cdb1468c915e27e5cec9af64f22f.svg\";","import {\n getAuthenticatedUser,\n getSiteConfig,\n logInfo,\n useAuthenticatedUser,\n useSiteConfig,\n useIntl\n} from '@openedx/frontend-base';\nimport { Container } from '@openedx/paragon';\nimport { useEffect } from 'react';\nimport { Link } from 'react-router-dom';\nimport messages from '../messages';\nimport Image from './Image';\nimport ParagonPreview from './ParagonPreview';\nimport appleImg from './apple.jpg';\nimport appleUrl from './apple.svg';\n\nfunction printTestResult(value) {\n return value ? '✅' : '❌';\n}\n\nexport default function ExamplePage() {\n const config = useSiteConfig();\n const authenticatedUser = useAuthenticatedUser();\n\n const intl = useIntl();\n\n useEffect(() => {\n logInfo('The example page can log info, which means logging is configured correctly.');\n }, []);\n\n return (\n <Container>\n <h1>{config.siteName} test page</h1>\n\n <h2>Links</h2>\n <p>Visit <Link to=\"/authenticated\">authenticated page</Link>.</p>\n <p>Visit <Link to=\"/error\">error page</Link>.</p>\n\n <h2>Context Config Test</h2>\n <p>Is context.config equal to getSiteConfig()? {printTestResult(config === getSiteConfig())}</p>\n <p>Is context.authenticatedUser equal to getAuthenticatedUser()? {printTestResult(authenticatedUser === getAuthenticatedUser())}</p>\n\n <h2>SCSS parsing tests</h2>\n <p><span className=\"red-text\">&quot;The Apples&quot;</span> should be red (<code>color: red;</code> via <code>.red-text</code> CSS class in SCSS stylesheet)</p>\n\n <h2>TSX parsing tests</h2>\n <Image src={appleUrl} alt=\"apple.svg displayed in Image.tsx\" style={{ width: '10rem' }} />\n\n <h2>SVG import test</h2>\n <img src={appleUrl} alt=\"apple.svg displayed in <img> tag\" style={{ width: '10rem' }} />\n\n <h2>JPG import test</h2>\n <p><img src={appleImg} alt=\"apple.jpg displayed in <img> tag\" style={{ width: '10rem' }} /></p>\n <p>Photo by Louis Hansel @shotsoflouis on Unsplash</p>\n\n <h2>i18n formatMessage test</h2>\n <p>{intl.formatMessage(messages['test-site.message'])}</p>\n\n <h2>Authenticated User Test</h2>\n {authenticatedUser !== null ? (\n <div>\n <p>Authenticated Username: <strong>{authenticatedUser.username}</strong></p>\n <p>\n Authenticated user&apos;s name:\n <strong>{authenticatedUser.username}</strong>\n (Only available if user account has been fetched)\n </p>\n </div>\n ) : (\n <p>Unauthenticated {printTestResult(authenticatedUser === null)}</p>\n )}\n\n <h2>Right-to-left language handling tests</h2>\n <p className=\"text-align-right\">I&apos;m aligned right, but left in RTL.</p>\n <ParagonPreview />\n </Container>\n );\n}\n"],"names":["alt","rest","Stack","forwardRef","_ref","ref","direction","gap","reversed","children","className","React","classNames","propTypes","PropTypes","isRequired","defaultProps","undefined","PARAGON_THEME","Button","paragon","themeUrls","core","fileName","href","target","rel","variants","light","brand","JSON","stringify","printTestResult","value","ExamplePage","config","authenticatedUser","intl","useIntl","useEffect","Container","siteName","to","src","style","width","apple","formatMessage","username"],"sourceRoot":""}
@@ -1,2 +0,0 @@
1
- "use strict";(self.webpackChunktest_site=self.webpackChunktest_site||[]).push([[362],{5362:(e,s,t)=>{t.r(s),t.d(s,{default:()=>u});var i=t(7517),n=t(8313),r=t(8083),a=t(3879),c=t(2880),h=t(7409);const o=(0,t(7050).YK)({loading:{id:"loading.message.text",defaultMessage:"Loading"},unexpectedError:{id:"unexpected.error.message.text",defaultMessage:"Oops! An error occurred. Please refresh the screen to try again."}}),d=()=>{const{formatMessage:e}=(0,r.A)();return(0,i.jsx)("div",{children:(0,i.jsx)("h2",{children:e(o.unexpectedError)})})};function l({children:e,className:s,style:t={},ready:r=!0,errorFallbackComponent:o}){const[l,u]=(0,n.useState)({width:0,height:0}),g=(0,n.useMemo)((()=>Object.assign(Object.assign({},l),t)),[l,t]),f=null!=o?o:d;return(0,h.in)(c.GV,(({payload:e})=>{u({width:e.width,height:e.height})})),(0,n.useEffect)((()=>((0,h.dh)(),()=>{(0,h.wt)()})),[]),(0,n.useEffect)((()=>{r&&(0,h.uj)()}),[r]),(0,i.jsx)("div",{className:s,style:g,children:(0,i.jsx)(a.A,{fallbackComponent:(0,i.jsx)(f,{}),children:e})})}function u(){return(0,i.jsx)(l,{children:(0,i.jsxs)("section",{className:"bg-light p-3 h-100",children:[(0,i.jsx)("h4",{children:"Inserted iFrame Widget"}),(0,i.jsx)("p",{children:"This is a component that lives in the test-site but is loaded into the page via an iframe. This emulates a real-world scenario. It is NOT testing for cross-origin security issues though, since it's on the same host name."})]})})}}}]);
2
- //# sourceMappingURL=362.536eff787d2380fe246c.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"362.536eff787d2380fe246c.js","mappings":"mMAEA,MAaA,GAbiB,E,QAAA,IAAe,CAC9BA,QAAS,CAAF,oDAKPC,gBAAiB,CAAF,wHCSXC,EAAuB,KAC3B,MAAM,cAAEC,IAAkB,EAAAC,EAAA,KAC1B,OACE,0BACE,wBACGD,EAAc,EAASF,sBAcjB,SAASI,GAAqB,SAC3CC,EAAQ,UAAEC,EAAS,MAAEC,EAAQ,CAAC,EAAC,MAAEC,GAAQ,EAAI,uBAAEC,IAE/C,MAAOC,EAAYC,IAAiB,IAAAC,UAAS,CAC3CC,MAAO,EACPC,OAAQ,IAGJC,GAAa,IAAAC,UAAQ,IAAO,OAAD,wBAC5BN,GACAH,IACD,CAACG,EAAYH,IAIXU,EAAgBR,QAAAA,EAA0BR,EAyBhD,OAvBA,QAAa,MAAe,EAAGiB,cAC7BP,EAAc,CACZE,MAAOK,EAAQL,MACfC,OAAQI,EAAQJ,aAIpB,IAAAK,YAAU,MACR,UAEO,MACL,aAED,KAEH,IAAAA,YAAU,KAGJX,IACF,YAED,CAACA,KAGF,gBAAKF,UAAWA,EAAWC,MAAOQ,EAAU,UAC1C,SAACK,EAAA,EAAa,CAACC,mBAAmB,SAACJ,EAAa,IAAG,SAChDZ,KAIT,CCjFe,SAASiB,IACtB,OACE,SAAClB,EAAoB,WACnB,qBAASE,UAAU,qBAAoB,WACrC,oDACA,8PAMR,C","sources":["webpack://test-site/./node_modules/@openedx/frontend-base/runtime/slots/widget/iframe/IFrameContentWrapper.messages.tsx","webpack://test-site/./node_modules/@openedx/frontend-base/runtime/slots/widget/iframe/IFrameContentWrapper.tsx","webpack://test-site/./src/iframe-widget/IframeWidget.tsx"],"sourcesContent":["import { defineMessages } from '../../../i18n';\n\nconst messages = defineMessages({\n loading: {\n id: 'loading.message.text',\n defaultMessage: 'Loading',\n description: 'the feature is currently loading',\n },\n unexpectedError: {\n id: 'unexpected.error.message.text',\n defaultMessage: ' Oops! An error occurred. Please refresh the screen to try again.',\n description: 'error message when an unexpected error occurs',\n },\n});\n\nexport default messages;\n","import {\n FunctionComponent,\n ReactNode,\n useEffect, useMemo, useState,\n} from 'react';\n\nimport { useIntl } from '../../../i18n';\nimport { ErrorBoundary } from '../../../react';\nimport { IFRAME_RESIZE } from './constants';\nimport {\n dispatchMountedEvent,\n dispatchReadyEvent,\n dispatchUnmountedEvent,\n useHostEvent\n} from './hooks';\nimport messages from './IFrameContentWrapper.messages';\n\nconst ErrorFallbackDefault = () => {\n const { formatMessage } = useIntl();\n return (\n <div>\n <h2>\n {formatMessage(messages.unexpectedError)}\n </h2>\n </div>\n );\n};\n\ninterface IFrameContentWrapperProps {\n children: ReactNode,\n className?: string,\n style?: Record<string, string>,\n ready?: boolean,\n errorFallbackComponent?: FunctionComponent,\n}\n\nexport default function IFrameContentWrapper({\n children, className, style = {}, ready = true, errorFallbackComponent,\n}: IFrameContentWrapperProps) {\n const [dimensions, setDimensions] = useState({\n width: 0,\n height: 0,\n });\n\n const finalStyle = useMemo(() => ({\n ...dimensions,\n ...style,\n }), [dimensions, style]);\n\n // Need to confirm: When an error is caught here, the logging will be sent to the child MFE's logging service\n\n const ErrorFallback = errorFallbackComponent ?? ErrorFallbackDefault;\n\n useHostEvent(IFRAME_RESIZE, ({ payload }) => {\n setDimensions({\n width: payload.width,\n height: payload.height,\n });\n });\n\n useEffect(() => {\n dispatchMountedEvent();\n\n return () => {\n dispatchUnmountedEvent();\n };\n }, []);\n\n useEffect(() => {\n // Ready defaults to true, but can be used to defer rendering the Plugin until certain processes\n // have occurred or conditions have been met\n if (ready) {\n dispatchReadyEvent();\n }\n }, [ready]);\n\n return (\n <div className={className} style={finalStyle}>\n <ErrorBoundary fallbackComponent={<ErrorFallback />}>\n {children}\n </ErrorBoundary>\n </div>\n );\n};\n","import { IFrameContentWrapper } from '@openedx/frontend-base';\n\nexport default function IframeWidget() {\n return (\n <IFrameContentWrapper>\n <section className=\"bg-light p-3 h-100\">\n <h4>Inserted iFrame Widget</h4>\n <p>\n This is a component that lives in the test-site but is loaded into the page via an iframe. This emulates a real-world scenario. It is NOT testing for cross-origin security issues though, since it&apos;s on the same host name.\n </p>\n </section>\n </IFrameContentWrapper>\n );\n}\n"],"names":["loading","unexpectedError","ErrorFallbackDefault","formatMessage","useIntl","IFrameContentWrapper","children","className","style","ready","errorFallbackComponent","dimensions","setDimensions","useState","width","height","finalStyle","useMemo","ErrorFallback","payload","useEffect","ErrorBoundary","fallbackComponent","IframeWidget"],"sourceRoot":""}
@@ -1,2 +0,0 @@
1
- "use strict";(self.webpackChunktest_site=self.webpackChunktest_site||[]).push([[653],{8653:(e,s,t)=>{t.r(s),t.d(s,{default:()=>h});var a=t(7517),i=t(3273),n=t(5029),c=t(6024);function h(){const e=(0,n.QR)(),s=(0,n.zn)();return(0,a.jsxs)("main",{className:"p-3",children:[(0,a.jsxs)("h1",{children:[s.siteName," authenticated page."]}),(0,a.jsx)(c.A,{id:"authenticated.page.content",defaultMessage:"This is a localized message. Try it in French."}),(0,a.jsx)("p",{children:null===e?"You are not authenticated.":`Hi there, ${e.username}.`}),(0,a.jsxs)("p",{children:["Visit ",(0,a.jsx)(i.N_,{to:"/",children:"public page"}),"."]})]})}}}]);
2
- //# sourceMappingURL=653.486966b108d224551296.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"653.486966b108d224551296.js","mappings":"+KAKe,SAASA,IACtB,MAAMC,GAAoB,UACpBC,GAAS,UAEf,OACE,kBAAMC,UAAU,MAAK,WACnB,0BAAKD,EAAOE,SAAQ,2BACpB,SAAC,IAAgB,oGACjB,uBAA0B,OAAtBH,EAA6B,6BAA+B,aAAaA,EAAkBI,eAC/F,mCAAS,SAAC,KAAI,CAACC,GAAG,IAAG,yBAAmB,SAG9C,C","sources":["webpack://test-site/./src/authenticated-page/AuthenticatedPage.tsx"],"sourcesContent":["import { Link } from 'react-router-dom';\n\nimport { useAuthenticatedUser, useSiteConfig } from '@openedx/frontend-base';\nimport { FormattedMessage } from 'react-intl';\n\nexport default function AuthenticatedPage() {\n const authenticatedUser = useAuthenticatedUser();\n const config = useSiteConfig();\n\n return (\n <main className=\"p-3\">\n <h1>{config.siteName} authenticated page.</h1>\n <FormattedMessage id=\"authenticated.page.content\" defaultMessage=\"This is a localized message. Try it in French.\" description=\"This is a test message to prove localization works.\" />\n <p>{authenticatedUser === null ? 'You are not authenticated.' : `Hi there, ${authenticatedUser.username}.`}</p>\n <p>Visit <Link to=\"/\">public page</Link>.</p>\n </main>\n );\n}\n"],"names":["AuthenticatedPage","authenticatedUser","config","className","siteName","username","to"],"sourceRoot":""}