@openedx/frontend-base 1.0.0-alpha.1 → 1.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/config/eslint/base.eslint.config.js +1 -1
  2. package/config/jest/jest.config.js +1 -0
  3. package/config/types.js +0 -2
  4. package/config/webpack/common-config/all/getStylesheetRule.js +1 -1
  5. package/config/webpack/webpack.config.build.js +1 -11
  6. package/config/webpack/webpack.config.dev.js +5 -11
  7. package/config/webpack/webpack.config.dev.shell.js +5 -11
  8. package/package.json +4 -3
  9. package/runtime/config/index.ts +2 -3
  10. package/runtime/index.ts +5 -0
  11. package/runtime/jest.config.js +1 -0
  12. package/runtime/react/SiteProvider.tsx +26 -3
  13. package/runtime/react/constants.ts +3 -0
  14. package/runtime/react/hooks/index.ts +8 -0
  15. package/runtime/react/hooks/theme/index.ts +2 -0
  16. package/runtime/react/hooks/theme/useTheme.test.ts +221 -0
  17. package/runtime/react/hooks/theme/useTheme.ts +179 -0
  18. package/runtime/react/hooks/theme/useThemeConfig.test.ts +107 -0
  19. package/runtime/react/hooks/theme/useThemeConfig.ts +34 -0
  20. package/runtime/react/hooks/theme/useThemeCore.test.ts +65 -0
  21. package/runtime/react/hooks/theme/useThemeCore.ts +52 -0
  22. package/runtime/react/hooks/theme/useThemeVariants.test.ts +97 -0
  23. package/runtime/react/hooks/theme/useThemeVariants.ts +116 -0
  24. package/runtime/react/hooks/theme/useTrackColorSchemeChoice.test.ts +54 -0
  25. package/runtime/react/hooks/theme/useTrackColorSchemeChoice.ts +30 -0
  26. package/runtime/react/hooks/theme/utils.ts +11 -0
  27. package/runtime/react/hooks/useActiveRoles.ts +15 -0
  28. package/runtime/react/hooks/useActiveRouteRoleWatcher.ts +31 -0
  29. package/runtime/react/hooks/useAppConfig.ts +9 -0
  30. package/runtime/react/hooks/useAuthenticatedUser.test.tsx +41 -0
  31. package/runtime/react/hooks/useAuthenticatedUser.ts +9 -0
  32. package/runtime/react/hooks/useSiteConfig.test.tsx +13 -0
  33. package/runtime/react/hooks/useSiteConfig.ts +9 -0
  34. package/runtime/react/hooks/useSiteEvent.ts +24 -0
  35. package/runtime/react/reducers.ts +40 -0
  36. package/runtime/setupTest.js +0 -35
  37. package/runtime/slots/widget/iframe/hooks.ts +1 -1
  38. package/runtime/testing/initializeMockApp.ts +5 -0
  39. package/shell/app.scss +2 -1
  40. package/shell/jest.config.js +1 -0
  41. package/shell/setupTest.js +0 -35
  42. package/shell/site.tsx +1 -1
  43. package/tools/dist/cli/openedx.js +1 -15
  44. package/tools/dist/cli/utils/printUsage.js +0 -9
  45. package/tools/dist/eslint/base.eslint.config.js +1 -1
  46. package/tools/dist/jest/jest.config.js +1 -0
  47. package/tools/dist/types.js +0 -2
  48. package/tools/dist/webpack/common-config/all/getStylesheetRule.js +1 -1
  49. package/tools/dist/webpack/webpack.config.build.js +1 -11
  50. package/tools/dist/webpack/webpack.config.dev.js +5 -11
  51. package/tools/dist/webpack/webpack.config.dev.shell.js +5 -11
  52. package/types.ts +20 -0
  53. package/config/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.js +0 -108
  54. package/config/webpack/plugins/paragon-webpack-plugin/index.js +0 -7
  55. package/config/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.js +0 -64
  56. package/config/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.js +0 -53
  57. package/config/webpack/plugins/paragon-webpack-plugin/utils/index.js +0 -9
  58. package/config/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.js +0 -114
  59. package/config/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.js +0 -146
  60. package/config/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.js +0 -126
  61. package/config/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.js +0 -57
  62. package/config/webpack/types.js +0 -2
  63. package/config/webpack/utils/paragonUtils.js +0 -138
  64. package/runtime/react/hooks.test.jsx +0 -104
  65. package/runtime/react/hooks.ts +0 -106
  66. package/tools/dist/cli/commands/pack.js +0 -14
  67. package/tools/dist/cli/commands/release.js +0 -28
  68. package/tools/dist/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.js +0 -108
  69. package/tools/dist/webpack/plugins/paragon-webpack-plugin/index.js +0 -7
  70. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.js +0 -64
  71. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.js +0 -53
  72. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/index.js +0 -9
  73. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.js +0 -114
  74. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.js +0 -146
  75. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.js +0 -126
  76. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.js +0 -57
  77. package/tools/dist/webpack/types.js +0 -2
  78. package/tools/dist/webpack/utils/paragonUtils.js +0 -138
@@ -0,0 +1,54 @@
1
+ import { renderHook } from '@testing-library/react';
2
+ import { sendTrackEvent } from '../../../analytics';
3
+ import useTrackColorSchemeChoice from './useTrackColorSchemeChoice';
4
+
5
+ jest.mock('../../../analytics');
6
+
7
+ const mockAddEventListener = jest.fn();
8
+ const mockRemoveEventListener = jest.fn();
9
+ let matchesMock;
10
+
11
+ Object.defineProperty(window, 'matchMedia', {
12
+ value: jest.fn(() => ({
13
+ addEventListener: mockAddEventListener,
14
+ removeEventListener: mockRemoveEventListener,
15
+ matches: matchesMock,
16
+ })),
17
+ });
18
+
19
+ describe('useTrackColorSchemeChoice hook', () => {
20
+ afterEach(() => {
21
+ mockAddEventListener.mockClear();
22
+ mockRemoveEventListener.mockClear();
23
+ jest.mocked(sendTrackEvent).mockClear();
24
+ });
25
+
26
+ it('sends dark preferred color schema event if query matches', async () => {
27
+ matchesMock = true;
28
+ renderHook(() => useTrackColorSchemeChoice());
29
+
30
+ expect(sendTrackEvent).toHaveBeenCalledTimes(1);
31
+ expect(sendTrackEvent).toHaveBeenCalledWith(
32
+ 'openedx.ui.frontend-base.prefers-color-scheme.selected',
33
+ { preferredColorScheme: 'dark' },
34
+ );
35
+ });
36
+
37
+ it('sends light preferred color schema event if query does not match', async () => {
38
+ matchesMock = false;
39
+ renderHook(() => useTrackColorSchemeChoice());
40
+
41
+ expect(sendTrackEvent).toHaveBeenCalledTimes(1);
42
+ expect(sendTrackEvent).toHaveBeenCalledWith(
43
+ 'openedx.ui.frontend-base.prefers-color-scheme.selected',
44
+ { preferredColorScheme: 'light' },
45
+ );
46
+ });
47
+
48
+ it('adds change event listener to matchMedia query', async () => {
49
+ renderHook(() => useTrackColorSchemeChoice());
50
+
51
+ expect(mockAddEventListener).toHaveBeenCalledTimes(1);
52
+ expect(mockAddEventListener).toHaveBeenCalledWith('change', expect.any(Function));
53
+ });
54
+ });
@@ -0,0 +1,30 @@
1
+ import { useEffect } from 'react';
2
+ import { sendTrackEvent } from '../../../analytics';
3
+
4
+ /**
5
+ * A React hook that tracks user's preferred color scheme (light or dark) and sends respective
6
+ * event to the tracking service.
7
+ *
8
+ * @memberof module:React
9
+ */
10
+ const useTrackColorSchemeChoice = () => {
11
+ useEffect(() => {
12
+ const trackColorSchemeChoice = ({ matches }) => {
13
+ const preferredColorScheme = matches ? 'dark' : 'light';
14
+ sendTrackEvent('openedx.ui.frontend-base.prefers-color-scheme.selected', { preferredColorScheme });
15
+ };
16
+ const colorSchemeQuery = window.matchMedia?.('(prefers-color-scheme: dark)');
17
+ if (colorSchemeQuery) {
18
+ // send user's initial choice
19
+ trackColorSchemeChoice(colorSchemeQuery);
20
+ colorSchemeQuery.addEventListener('change', trackColorSchemeChoice);
21
+ }
22
+ return () => {
23
+ if (colorSchemeQuery) {
24
+ colorSchemeQuery.removeEventListener('change', trackColorSchemeChoice);
25
+ }
26
+ };
27
+ }, []);
28
+ };
29
+
30
+ export default useTrackColorSchemeChoice;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Iterates through each given `<link>` element and removes it from the DOM.
3
+ * @param {HTMLLinkElement[]} existingLinks
4
+ */
5
+ export const removeExistingLinks = (existingLinks) => {
6
+ existingLinks.forEach((link) => {
7
+ link.remove();
8
+ });
9
+ };
10
+
11
+ export const isEmptyObject = (obj) => !obj || Object.keys(obj).length === 0;
@@ -0,0 +1,15 @@
1
+ import { useState } from 'react';
2
+ import { getActiveRoles } from '../../config';
3
+ import { ACTIVE_ROLES_CHANGED } from '../../constants';
4
+ import useSiteEvent from './useSiteEvent';
5
+
6
+ const useActiveRoles = () => {
7
+ const [roles, setRoles] = useState<string[]>(getActiveRoles());
8
+ useSiteEvent(ACTIVE_ROLES_CHANGED, () => {
9
+ setRoles(getActiveRoles());
10
+ });
11
+
12
+ return roles;
13
+ };
14
+
15
+ export default useActiveRoles;
@@ -0,0 +1,31 @@
1
+ import { useCallback, useEffect } from 'react';
2
+ import { useMatches } from 'react-router';
3
+ import { setActiveRouteRoles } from '../../config';
4
+ import { isRoleRouteObject } from '../../routing';
5
+
6
+ const useActiveRouteRoleWatcher = () => {
7
+ const matches = useMatches();
8
+
9
+ // We create this callback so we can use it right away to populate the default state value.
10
+ const findActiveRouteRoles = useCallback(() => {
11
+ // Starts with the widget roles and adds the others in.
12
+ const roles: string[] = [];
13
+
14
+ // Route roles
15
+ for (const match of matches) {
16
+ if (isRoleRouteObject(match)) {
17
+ if (!roles.includes(match.handle.role)) {
18
+ roles.push(match.handle.role);
19
+ }
20
+ }
21
+ }
22
+
23
+ return roles;
24
+ }, [matches]);
25
+
26
+ useEffect(() => {
27
+ setActiveRouteRoles(findActiveRouteRoles());
28
+ }, [matches, findActiveRouteRoles]);
29
+ };
30
+
31
+ export default useActiveRouteRoleWatcher;
@@ -0,0 +1,9 @@
1
+ import { useContext } from 'react';
2
+ import CurrentAppContext from '../CurrentAppContext';
3
+
4
+ const useAppConfig = () => {
5
+ const { appConfig } = useContext(CurrentAppContext);
6
+ return appConfig;
7
+ };
8
+
9
+ export default useAppConfig;
@@ -0,0 +1,41 @@
1
+ import { act, renderHook } from '@testing-library/react';
2
+ import { setAuthenticatedUser } from '../../auth';
3
+ import { initializeMockApp } from '../../testing';
4
+ import SiteProvider from '../SiteProvider';
5
+ import useAuthenticatedUser from './useAuthenticatedUser';
6
+
7
+ describe('useAuthenticatedUser', () => {
8
+ it('returns null when the user is anonymous', () => {
9
+ const { result } = renderHook(() => useAuthenticatedUser());
10
+ expect(result.current).toBeNull();
11
+ });
12
+
13
+ describe('with a user', () => {
14
+ const user = {
15
+ administrator: true,
16
+ email: 'admin@example.com',
17
+ name: 'Admin',
18
+ roles: ['admin'],
19
+ userId: 1,
20
+ username: 'admin-user',
21
+ avatar: 'http://localhost/admin.png',
22
+ };
23
+
24
+ beforeEach(() => {
25
+ initializeMockApp({
26
+ authenticatedUser: user,
27
+ });
28
+ });
29
+
30
+ afterEach(() => {
31
+ act(() => {
32
+ setAuthenticatedUser(null);
33
+ });
34
+ });
35
+
36
+ it('returns a User when the user exists', () => {
37
+ const { result } = renderHook(() => useAuthenticatedUser(), { wrapper: SiteProvider });
38
+ expect(result.current).toBe(user);
39
+ });
40
+ });
41
+ });
@@ -0,0 +1,9 @@
1
+ import { useContext } from 'react';
2
+ import SiteContext from '../SiteContext';
3
+
4
+ const useAuthenticatedUser = () => {
5
+ const { authenticatedUser } = useContext(SiteContext);
6
+ return authenticatedUser;
7
+ };
8
+
9
+ export default useAuthenticatedUser;
@@ -0,0 +1,13 @@
1
+ import { renderHook } from '@testing-library/react';
2
+ import siteConfig from 'site.config';
3
+ import { EnvironmentTypes } from '../../../types';
4
+ import useSiteConfig from './useSiteConfig';
5
+
6
+ describe('useSiteConfig', () => {
7
+ it('returns the site config', () => {
8
+ const { result } = renderHook(() => useSiteConfig());
9
+ expect(result.current).toHaveProperty('apps', siteConfig.apps);
10
+ expect(result.current).toHaveProperty('environment', EnvironmentTypes.TEST);
11
+ expect(result.current).toHaveProperty('baseUrl', 'http://localhost:8080');
12
+ });
13
+ });
@@ -0,0 +1,9 @@
1
+ import { useContext } from 'react';
2
+ import SiteContext from '../SiteContext';
3
+
4
+ const useSiteConfig = () => {
5
+ const { siteConfig } = useContext(SiteContext);
6
+ return siteConfig;
7
+ };
8
+
9
+ export default useSiteConfig;
@@ -0,0 +1,24 @@
1
+ import { useEffect } from 'react';
2
+ import { subscribe, unsubscribe } from '../../subscriptions';
3
+
4
+ /**
5
+ * A React hook that allows functional components to subscribe to application events. This should
6
+ * be used sparingly - for the most part, Context should be used higher-up in the application to
7
+ * provide necessary data to a given component, rather than utilizing a non-React-like Pub/Sub
8
+ * mechanism.
9
+ *
10
+ * @memberof module:React
11
+ * @param {string} type
12
+ * @param {function} callback
13
+ */
14
+ const useSiteEvent = (type, callback) => {
15
+ useEffect(() => {
16
+ subscribe(type, callback);
17
+
18
+ return () => {
19
+ unsubscribe(type, callback);
20
+ };
21
+ }, [callback, type]);
22
+ };
23
+
24
+ export default useSiteEvent;
@@ -0,0 +1,40 @@
1
+ import {
2
+ SET_THEME_VARIANT,
3
+ SET_IS_THEME_LOADED,
4
+ } from './constants';
5
+
6
+ export function themeReducer(state, action) {
7
+ switch (action.type) {
8
+ case SET_THEME_VARIANT: {
9
+ const requestedThemeVariant = action.payload;
10
+ return {
11
+ ...state,
12
+ themeVariant: requestedThemeVariant,
13
+ };
14
+ }
15
+ case SET_IS_THEME_LOADED: {
16
+ const requestedIsThemeLoaded = action.payload;
17
+ return {
18
+ ...state,
19
+ isThemeLoaded: requestedIsThemeLoaded,
20
+ };
21
+ }
22
+ default:
23
+ return state;
24
+ }
25
+ }
26
+
27
+ const setThemeVariant = (payload) => ({
28
+ type: SET_THEME_VARIANT,
29
+ payload,
30
+ });
31
+
32
+ const setThemeLoaded = (payload) => ({
33
+ type: SET_IS_THEME_LOADED,
34
+ payload,
35
+ });
36
+
37
+ export const themeActions = {
38
+ setThemeVariant,
39
+ setThemeLoaded,
40
+ };
@@ -12,38 +12,3 @@ jest.mock('universal-cookie', () => {
12
12
  });
13
13
 
14
14
  mergeSiteConfig(siteConfig);
15
-
16
- global.PARAGON_THEME = {
17
- paragon: {
18
- version: '1.0.0',
19
- themeUrls: {
20
- core: {
21
- fileName: 'core.min.css',
22
- },
23
- defaults: {
24
- light: 'light',
25
- },
26
- variants: {
27
- light: {
28
- fileName: 'light.min.css',
29
- },
30
- },
31
- },
32
- },
33
- brand: {
34
- version: '1.0.0',
35
- themeUrls: {
36
- core: {
37
- fileName: 'core.min.css',
38
- },
39
- defaults: {
40
- light: 'light',
41
- },
42
- variants: {
43
- light: {
44
- fileName: 'light.min.css',
45
- },
46
- },
47
- },
48
- },
49
- };
@@ -127,7 +127,7 @@ export function dispatchUnmountedEvent() {
127
127
  */
128
128
  export function useElementSize() {
129
129
  // Holds a reference to the ResizeObserver
130
- const observerRef = useRef<ResizeObserver>();
130
+ const observerRef = useRef<ResizeObserver | null>(null);
131
131
 
132
132
  const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
133
133
  const [offset, setOffset] = useState({ x: 0, y: 0 });
@@ -1,5 +1,7 @@
1
1
  import siteConfig from 'site.config';
2
2
 
3
+ import { LocalizedMessages, User } from '../../types';
4
+
3
5
  import { configureAnalytics, MockAnalyticsService } from '../analytics';
4
6
  import { configureAuth, MockAuthService, setAuthenticatedUser } from '../auth';
5
7
  import { getSiteConfig, mergeSiteConfig } from '../config';
@@ -47,6 +49,9 @@ import mockMessages from './mockMessages';
47
49
  export default function initializeMockApp({
48
50
  messages = mockMessages,
49
51
  authenticatedUser = null,
52
+ }: {
53
+ messages?: LocalizedMessages,
54
+ authenticatedUser?: User | null,
50
55
  } = {}) {
51
56
  const config = siteConfig;
52
57
  mergeSiteConfig(config);
package/shell/app.scss CHANGED
@@ -1,4 +1,5 @@
1
- @use "@openedx/paragon/scss/core/core.scss";
1
+ @use "@openedx/paragon/dist/core.min.css";
2
+ @use "@openedx/paragon/dist/light.min.css";
2
3
 
3
4
  .flex-basis-0 {
4
5
  flex-basis: 0 !important;
@@ -7,6 +7,7 @@ module.exports = {
7
7
  '\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/__mocks__/file.js',
8
8
  '\\.(css|scss)$': require.resolve('identity-obj-proxy'),
9
9
  'site.config': '<rootDir>/site.config.test.tsx',
10
+ '^@src/(.*)$': '<rootDir>/src/$1',
10
11
  },
11
12
  testEnvironment: 'jsdom',
12
13
  testEnvironmentOptions: {
@@ -11,38 +11,3 @@ jest.mock('universal-cookie', () => {
11
11
  });
12
12
 
13
13
  mergeSiteConfig(siteConfig);
14
-
15
- global.PARAGON_THEME = {
16
- paragon: {
17
- version: '1.0.0',
18
- themeUrls: {
19
- core: {
20
- fileName: 'core.min.css',
21
- },
22
- defaults: {
23
- light: 'light',
24
- },
25
- variants: {
26
- light: {
27
- fileName: 'light.min.css',
28
- },
29
- },
30
- },
31
- },
32
- brand: {
33
- version: '1.0.0',
34
- themeUrls: {
35
- core: {
36
- fileName: 'core.min.css',
37
- },
38
- defaults: {
39
- light: 'light',
40
- },
41
- variants: {
42
- light: {
43
- fileName: 'light.min.css',
44
- },
45
- },
46
- },
47
- },
48
- };
package/shell/site.tsx CHANGED
@@ -25,7 +25,7 @@ subscribe(SITE_READY, async () => {
25
25
  root.render(
26
26
  <StrictMode>
27
27
  <QueryClientProvider client={queryClient}>
28
- <RouterProvider router={router} />,
28
+ <RouterProvider router={router} />
29
29
  </QueryClientProvider>
30
30
  </StrictMode>
31
31
  );
@@ -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`);
@@ -31,7 +31,6 @@ module.exports = tseslint.config(eslint.configs.recommended, ...tseslint.configs
31
31
  ...globals.browser,
32
32
  ...globals.node,
33
33
  ...globals.jest,
34
- PARAGON_THEME: 'readonly',
35
34
  newrelic: 'readonly',
36
35
  },
37
36
  },
@@ -79,6 +78,7 @@ module.exports = tseslint.config(eslint.configs.recommended, ...tseslint.configs
79
78
  caughtErrors: 'none',
80
79
  }],
81
80
  '@typescript-eslint/no-empty-function': 'off',
81
+ '@typescript-eslint/prefer-nullish-coalescing': 'off',
82
82
  '@stylistic/semi': ['error', 'always', { omitLastInOneLineBlock: true, omitLastInOneLineClassBody: true }],
83
83
  '@stylistic/quotes': ['error', 'single', {
84
84
  avoidEscape: true,
@@ -9,6 +9,7 @@ module.exports = {
9
9
  moduleNameMapper: {
10
10
  '\\.(css|scss)$': require.resolve('identity-obj-proxy'),
11
11
  'site.config': path.resolve(process.cwd(), './site.config.test.tsx'),
12
+ '^@src/(.*)$': '<rootDir>/src/$1',
12
13
  },
13
14
  collectCoverageFrom: [
14
15
  'src/**/*.{js,jsx,ts,tsx}',
@@ -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";
@@ -87,7 +87,7 @@ function getStyleUseConfig(mode) {
87
87
  ],
88
88
  // Silences compiler deprecation warnings. They mostly come from bootstrap and/or paragon.
89
89
  quietDeps: true,
90
- silenceDeprecations: ['abs-percent', 'color-functions', 'import', 'mixed-decls', 'global-builtin', 'legacy-js-api'],
90
+ silenceDeprecations: ['abs-percent', 'color-functions', 'import', 'global-builtin', 'legacy-js-api'],
91
91
  },
92
92
  },
93
93
  },
@@ -9,13 +9,9 @@ const path_1 = __importDefault(require("path"));
9
9
  const webpack_bundle_analyzer_1 = require("webpack-bundle-analyzer");
10
10
  const webpack_remove_empty_scripts_1 = __importDefault(require("webpack-remove-empty-scripts"));
11
11
  const common_config_1 = require("./common-config");
12
- const ParagonWebpackPlugin_1 = __importDefault(require("./plugins/paragon-webpack-plugin/ParagonWebpackPlugin"));
13
12
  const getLocalAliases_1 = __importDefault(require("./utils/getLocalAliases"));
14
13
  const getPublicPath_1 = __importDefault(require("./utils/getPublicPath"));
15
14
  const getResolvedSiteConfigPath_1 = __importDefault(require("./utils/getResolvedSiteConfigPath"));
16
- const paragonUtils_1 = require("./utils/paragonUtils");
17
- const paragonThemeCss = (0, paragonUtils_1.getParagonThemeCss)(process.cwd());
18
- const brandThemeCss = (0, paragonUtils_1.getParagonThemeCss)(process.cwd(), { isBrandOverride: true });
19
15
  const aliases = (0, getLocalAliases_1.default)();
20
16
  const resolvedSiteConfigPath = (0, getResolvedSiteConfigPath_1.default)('site.config.build.tsx');
21
17
  const config = {
@@ -23,8 +19,6 @@ const config = {
23
19
  devtool: 'source-map',
24
20
  entry: {
25
21
  app: path_1.default.resolve(process.cwd(), 'node_modules/@openedx/frontend-base/shell/site'),
26
- ...(0, paragonUtils_1.getParagonEntryPoints)(paragonThemeCss),
27
- ...(0, paragonUtils_1.getParagonEntryPoints)(brandThemeCss),
28
22
  },
29
23
  output: {
30
24
  filename: '[name].[chunkhash].js',
@@ -36,6 +30,7 @@ const config = {
36
30
  alias: {
37
31
  ...aliases,
38
32
  'site.config': resolvedSiteConfigPath,
33
+ '@src': path_1.default.resolve(process.cwd(), 'src'),
39
34
  },
40
35
  extensions: ['.js', '.jsx', '.ts', '.tsx'],
41
36
  },
@@ -51,10 +46,6 @@ const config = {
51
46
  runtimeChunk: 'single',
52
47
  splitChunks: {
53
48
  chunks: 'all',
54
- cacheGroups: {
55
- ...(0, paragonUtils_1.getParagonCacheGroups)(paragonThemeCss),
56
- ...(0, paragonUtils_1.getParagonCacheGroups)(brandThemeCss),
57
- },
58
49
  },
59
50
  minimizer: (0, common_config_1.getImageMinimizer)(),
60
51
  },
@@ -65,7 +56,6 @@ const config = {
65
56
  // See: https://www.npmjs.com/package/webpack-remove-empty-scripts#usage-with-mini-css-extract-plugin
66
57
  new webpack_remove_empty_scripts_1.default(),
67
58
  // Writes the extracted CSS from each entry to a file in the output directory.
68
- new ParagonWebpackPlugin_1.default(),
69
59
  new mini_css_extract_plugin_1.default({
70
60
  filename: '[name].[chunkhash].css',
71
61
  }),
@@ -9,20 +9,14 @@ const mini_css_extract_plugin_1 = __importDefault(require("mini-css-extract-plug
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const webpack_remove_empty_scripts_1 = __importDefault(require("webpack-remove-empty-scripts"));
11
11
  const common_config_1 = require("./common-config");
12
- const ParagonWebpackPlugin_1 = __importDefault(require("./plugins/paragon-webpack-plugin/ParagonWebpackPlugin"));
13
12
  const getLocalAliases_1 = __importDefault(require("./utils/getLocalAliases"));
14
13
  const getPublicPath_1 = __importDefault(require("./utils/getPublicPath"));
15
14
  const getResolvedSiteConfigPath_1 = __importDefault(require("./utils/getResolvedSiteConfigPath"));
16
- const paragonUtils_1 = require("./utils/paragonUtils");
17
- const paragonThemeCss = (0, paragonUtils_1.getParagonThemeCss)(process.cwd());
18
- const brandThemeCss = (0, paragonUtils_1.getParagonThemeCss)(process.cwd(), { isBrandOverride: true });
19
15
  const aliases = (0, getLocalAliases_1.default)();
20
16
  const resolvedSiteConfigPath = (0, getResolvedSiteConfigPath_1.default)('site.config.dev.tsx');
21
17
  const config = {
22
18
  entry: {
23
19
  app: path_1.default.resolve(process.cwd(), 'node_modules/@openedx/frontend-base/shell/site'),
24
- ...(0, paragonUtils_1.getParagonEntryPoints)(paragonThemeCss),
25
- ...(0, paragonUtils_1.getParagonEntryPoints)(brandThemeCss),
26
20
  },
27
21
  output: {
28
22
  path: path_1.default.resolve(process.cwd(), './dist'),
@@ -32,6 +26,7 @@ const config = {
32
26
  alias: {
33
27
  ...aliases,
34
28
  'site.config': resolvedSiteConfigPath,
29
+ '@src': path_1.default.resolve(process.cwd(), 'src'),
35
30
  },
36
31
  extensions: ['.js', '.jsx', '.ts', '.tsx'],
37
32
  },
@@ -47,10 +42,6 @@ const config = {
47
42
  optimization: {
48
43
  splitChunks: {
49
44
  chunks: 'all',
50
- cacheGroups: {
51
- ...(0, paragonUtils_1.getParagonCacheGroups)(paragonThemeCss),
52
- ...(0, paragonUtils_1.getParagonCacheGroups)(brandThemeCss),
53
- },
54
45
  },
55
46
  minimizer: (0, common_config_1.getImageMinimizer)(),
56
47
  },
@@ -60,7 +51,6 @@ const config = {
60
51
  // This helps to clean up the final bundle application
61
52
  // See: https://www.npmjs.com/package/webpack-remove-empty-scripts#usage-with-mini-css-extract-plugin
62
53
  new webpack_remove_empty_scripts_1.default(),
63
- new ParagonWebpackPlugin_1.default(),
64
54
  // Writes the extracted CSS from each entry to a file in the output directory.
65
55
  new mini_css_extract_plugin_1.default({
66
56
  filename: '[name].css',
@@ -72,5 +62,9 @@ const config = {
72
62
  // This configures webpack-dev-server which serves bundles from memory and provides live
73
63
  // reloading.
74
64
  devServer: (0, common_config_1.getDevServer)(),
65
+ // Limit the number of watched files to avoid `inotify` resource starvation.
66
+ watchOptions: {
67
+ ignored: /node_modules/
68
+ }
75
69
  };
76
70
  exports.default = config;