@openedx/frontend-base 1.0.0-alpha.6 → 1.0.0-alpha.8
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.
- package/config/eslint/base.eslint.config.js +1 -1
- package/config/webpack/common-config/all/getStylesheetRule.js +1 -1
- package/config/webpack/webpack.config.build.js +0 -11
- package/config/webpack/webpack.config.dev.js +0 -11
- package/config/webpack/webpack.config.dev.shell.js +0 -11
- package/package.json +4 -3
- package/runtime/config/index.ts +2 -3
- package/runtime/react/SiteProvider.tsx +26 -3
- package/runtime/react/constants.ts +3 -0
- package/runtime/react/hooks/index.ts +8 -0
- package/runtime/react/hooks/theme/index.ts +2 -0
- package/runtime/react/hooks/theme/useTheme.test.ts +221 -0
- package/runtime/react/hooks/theme/useTheme.ts +179 -0
- package/runtime/react/hooks/theme/useThemeConfig.test.ts +107 -0
- package/runtime/react/hooks/theme/useThemeConfig.ts +34 -0
- package/runtime/react/hooks/theme/useThemeCore.test.ts +65 -0
- package/runtime/react/hooks/theme/useThemeCore.ts +52 -0
- package/runtime/react/hooks/theme/useThemeVariants.test.ts +97 -0
- package/runtime/react/hooks/theme/useThemeVariants.ts +116 -0
- package/runtime/react/hooks/theme/useTrackColorSchemeChoice.test.ts +54 -0
- package/runtime/react/hooks/theme/useTrackColorSchemeChoice.ts +30 -0
- package/runtime/react/hooks/theme/utils.ts +11 -0
- package/runtime/react/hooks/useActiveRoles.ts +15 -0
- package/runtime/react/hooks/useActiveRouteRoleWatcher.ts +31 -0
- package/runtime/react/hooks/useAppConfig.ts +9 -0
- package/runtime/react/hooks/useAuthenticatedUser.test.tsx +41 -0
- package/runtime/react/hooks/useAuthenticatedUser.ts +9 -0
- package/runtime/react/hooks/useSiteConfig.test.tsx +13 -0
- package/runtime/react/hooks/useSiteConfig.ts +9 -0
- package/runtime/react/hooks/useSiteEvent.ts +24 -0
- package/runtime/react/reducers.ts +40 -0
- package/runtime/setupTest.js +0 -35
- package/runtime/testing/initializeMockApp.ts +5 -0
- package/shell/app.scss +2 -1
- package/shell/setupTest.js +0 -35
- package/tools/dist/eslint/base.eslint.config.js +1 -1
- package/tools/dist/webpack/common-config/all/getStylesheetRule.js +1 -1
- package/tools/dist/webpack/webpack.config.build.js +0 -11
- package/tools/dist/webpack/webpack.config.dev.js +0 -11
- package/tools/dist/webpack/webpack.config.dev.shell.js +0 -11
- package/types.ts +20 -0
- package/config/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.js +0 -108
- package/config/webpack/plugins/paragon-webpack-plugin/index.js +0 -7
- package/config/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.js +0 -64
- package/config/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.js +0 -53
- package/config/webpack/plugins/paragon-webpack-plugin/utils/index.js +0 -9
- package/config/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.js +0 -114
- package/config/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.js +0 -146
- package/config/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.js +0 -126
- package/config/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.js +0 -57
- package/config/webpack/types.js +0 -2
- package/config/webpack/utils/paragonUtils.js +0 -138
- package/runtime/react/hooks.test.jsx +0 -104
- package/runtime/react/hooks.ts +0 -106
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.js +0 -108
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/index.js +0 -7
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.js +0 -64
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.js +0 -53
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/index.js +0 -9
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.js +0 -114
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.js +0 -146
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.js +0 -126
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.js +0 -57
- package/tools/dist/webpack/types.js +0 -2
- package/tools/dist/webpack/utils/paragonUtils.js +0 -138
|
@@ -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,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
|
+
};
|
package/runtime/setupTest.js
CHANGED
|
@@ -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
|
-
};
|
|
@@ -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
package/shell/setupTest.js
CHANGED
|
@@ -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
|
-
};
|
|
@@ -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,
|
|
@@ -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', '
|
|
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',
|
|
@@ -51,10 +45,6 @@ const config = {
|
|
|
51
45
|
runtimeChunk: 'single',
|
|
52
46
|
splitChunks: {
|
|
53
47
|
chunks: 'all',
|
|
54
|
-
cacheGroups: {
|
|
55
|
-
...(0, paragonUtils_1.getParagonCacheGroups)(paragonThemeCss),
|
|
56
|
-
...(0, paragonUtils_1.getParagonCacheGroups)(brandThemeCss),
|
|
57
|
-
},
|
|
58
48
|
},
|
|
59
49
|
minimizer: (0, common_config_1.getImageMinimizer)(),
|
|
60
50
|
},
|
|
@@ -65,7 +55,6 @@ const config = {
|
|
|
65
55
|
// See: https://www.npmjs.com/package/webpack-remove-empty-scripts#usage-with-mini-css-extract-plugin
|
|
66
56
|
new webpack_remove_empty_scripts_1.default(),
|
|
67
57
|
// Writes the extracted CSS from each entry to a file in the output directory.
|
|
68
|
-
new ParagonWebpackPlugin_1.default(),
|
|
69
58
|
new mini_css_extract_plugin_1.default({
|
|
70
59
|
filename: '[name].[chunkhash].css',
|
|
71
60
|
}),
|
|
@@ -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'),
|
|
@@ -47,10 +41,6 @@ const config = {
|
|
|
47
41
|
optimization: {
|
|
48
42
|
splitChunks: {
|
|
49
43
|
chunks: 'all',
|
|
50
|
-
cacheGroups: {
|
|
51
|
-
...(0, paragonUtils_1.getParagonCacheGroups)(paragonThemeCss),
|
|
52
|
-
...(0, paragonUtils_1.getParagonCacheGroups)(brandThemeCss),
|
|
53
|
-
},
|
|
54
44
|
},
|
|
55
45
|
minimizer: (0, common_config_1.getImageMinimizer)(),
|
|
56
46
|
},
|
|
@@ -60,7 +50,6 @@ const config = {
|
|
|
60
50
|
// This helps to clean up the final bundle application
|
|
61
51
|
// See: https://www.npmjs.com/package/webpack-remove-empty-scripts#usage-with-mini-css-extract-plugin
|
|
62
52
|
new webpack_remove_empty_scripts_1.default(),
|
|
63
|
-
new ParagonWebpackPlugin_1.default(),
|
|
64
53
|
// Writes the extracted CSS from each entry to a file in the output directory.
|
|
65
54
|
new mini_css_extract_plugin_1.default({
|
|
66
55
|
filename: '[name].css',
|
|
@@ -11,21 +11,15 @@ const path_1 = __importDefault(require("path"));
|
|
|
11
11
|
const react_refresh_typescript_1 = __importDefault(require("react-refresh-typescript"));
|
|
12
12
|
const webpack_remove_empty_scripts_1 = __importDefault(require("webpack-remove-empty-scripts"));
|
|
13
13
|
const common_config_1 = require("./common-config");
|
|
14
|
-
const ParagonWebpackPlugin_1 = __importDefault(require("./plugins/paragon-webpack-plugin/ParagonWebpackPlugin"));
|
|
15
14
|
const html_webpack_plugin_1 = __importDefault(require("html-webpack-plugin"));
|
|
16
15
|
const getLocalAliases_1 = __importDefault(require("./utils/getLocalAliases"));
|
|
17
16
|
const getPublicPath_1 = __importDefault(require("./utils/getPublicPath"));
|
|
18
17
|
const getResolvedSiteConfigPath_1 = __importDefault(require("./utils/getResolvedSiteConfigPath"));
|
|
19
|
-
const paragonUtils_1 = require("./utils/paragonUtils");
|
|
20
|
-
const paragonThemeCss = (0, paragonUtils_1.getParagonThemeCss)(process.cwd());
|
|
21
|
-
const brandThemeCss = (0, paragonUtils_1.getParagonThemeCss)(process.cwd(), { isBrandOverride: true });
|
|
22
18
|
const aliases = (0, getLocalAliases_1.default)();
|
|
23
19
|
const resolvedSiteConfigPath = (0, getResolvedSiteConfigPath_1.default)('shell/site.config.dev.tsx');
|
|
24
20
|
const config = {
|
|
25
21
|
entry: {
|
|
26
22
|
app: path_1.default.resolve(process.cwd(), 'shell/site'),
|
|
27
|
-
...(0, paragonUtils_1.getParagonEntryPoints)(paragonThemeCss),
|
|
28
|
-
...(0, paragonUtils_1.getParagonEntryPoints)(brandThemeCss),
|
|
29
23
|
},
|
|
30
24
|
output: {
|
|
31
25
|
path: path_1.default.resolve(process.cwd(), './dist'),
|
|
@@ -77,10 +71,6 @@ const config = {
|
|
|
77
71
|
optimization: {
|
|
78
72
|
splitChunks: {
|
|
79
73
|
chunks: 'all',
|
|
80
|
-
cacheGroups: {
|
|
81
|
-
...(0, paragonUtils_1.getParagonCacheGroups)(paragonThemeCss),
|
|
82
|
-
...(0, paragonUtils_1.getParagonCacheGroups)(brandThemeCss),
|
|
83
|
-
},
|
|
84
74
|
},
|
|
85
75
|
minimizer: (0, common_config_1.getImageMinimizer)(),
|
|
86
76
|
},
|
|
@@ -90,7 +80,6 @@ const config = {
|
|
|
90
80
|
// This helps to clean up the final bundle application
|
|
91
81
|
// See: https://www.npmjs.com/package/webpack-remove-empty-scripts#usage-with-mini-css-extract-plugin
|
|
92
82
|
new webpack_remove_empty_scripts_1.default(),
|
|
93
|
-
new ParagonWebpackPlugin_1.default(),
|
|
94
83
|
// Writes the extracted CSS from each entry to a file in the output directory.
|
|
95
84
|
new mini_css_extract_plugin_1.default({
|
|
96
85
|
filename: '[name].css',
|
package/types.ts
CHANGED
|
@@ -60,6 +60,9 @@ export interface OptionalSiteConfig {
|
|
|
60
60
|
externalLinkUrlOverrides: string[],
|
|
61
61
|
mfeConfigApiUrl: string | null,
|
|
62
62
|
|
|
63
|
+
// Theme
|
|
64
|
+
theme: Theme,
|
|
65
|
+
|
|
63
66
|
// Cookies
|
|
64
67
|
accessTokenCookieName: string,
|
|
65
68
|
languagePreferenceCookieName: string,
|
|
@@ -78,6 +81,23 @@ export interface OptionalSiteConfig {
|
|
|
78
81
|
|
|
79
82
|
export type SiteConfig = RequiredSiteConfig & Partial<OptionalSiteConfig>;
|
|
80
83
|
|
|
84
|
+
export interface ThemeVariant {
|
|
85
|
+
url: string,
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface ThemeDefaults {
|
|
89
|
+
light?: string,
|
|
90
|
+
dark?: string,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export type ThemeVariants = Record<string, ThemeVariant>;
|
|
94
|
+
|
|
95
|
+
export interface Theme {
|
|
96
|
+
core?: ThemeVariant,
|
|
97
|
+
defaults?: ThemeDefaults,
|
|
98
|
+
variants?: ThemeVariants,
|
|
99
|
+
}
|
|
100
|
+
|
|
81
101
|
export interface User {
|
|
82
102
|
administrator: boolean,
|
|
83
103
|
email: string,
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const webpack_1 = require("webpack");
|
|
4
|
-
const paragonUtils_1 = require("../../utils/paragonUtils");
|
|
5
|
-
const utils_1 = require("./utils");
|
|
6
|
-
// Get Paragon and brand versions / CSS files from disk.
|
|
7
|
-
const paragonVersion = (0, paragonUtils_1.getParagonVersion)(process.cwd());
|
|
8
|
-
const paragonThemeCss = (0, paragonUtils_1.getParagonThemeCss)(process.cwd());
|
|
9
|
-
const brandVersion = (0, paragonUtils_1.getParagonVersion)(process.cwd(), { isBrandOverride: true });
|
|
10
|
-
const brandThemeCss = (0, paragonUtils_1.getParagonThemeCss)(process.cwd(), { isBrandOverride: true });
|
|
11
|
-
/**
|
|
12
|
-
* 1. Injects `PARAGON_THEME` global variable into the HTML document during the Webpack compilation process.
|
|
13
|
-
* 2. Injects `<link rel="preload" as="style">` element(s) for the Paragon and brand CSS into the HTML document.
|
|
14
|
-
*/
|
|
15
|
-
class ParagonWebpackPlugin {
|
|
16
|
-
pluginName;
|
|
17
|
-
paragonThemeUrlsConfig;
|
|
18
|
-
processAssetsHandlers;
|
|
19
|
-
paragonMetadata;
|
|
20
|
-
constructor({ processAssetsHandlers = [] } = {}) {
|
|
21
|
-
this.pluginName = 'ParagonWebpackPlugin';
|
|
22
|
-
this.paragonThemeUrlsConfig = {};
|
|
23
|
-
this.paragonMetadata = {};
|
|
24
|
-
// List of handlers to be executed after processing assets during the Webpack compilation.
|
|
25
|
-
this.processAssetsHandlers = [
|
|
26
|
-
this.resolveParagonThemeUrlsFromConfig,
|
|
27
|
-
this.injectParagonMetadataIntoDocument,
|
|
28
|
-
this.injectParagonStylesheetsIntoDocument,
|
|
29
|
-
...processAssetsHandlers,
|
|
30
|
-
].map(handler => handler.bind(this));
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Resolves the MFE configuration from ``PARAGON_THEME_URLS`` in the environment variables. `
|
|
34
|
-
*
|
|
35
|
-
* @returns {Object} Metadata about the Paragon and brand theme URLs from configuration.
|
|
36
|
-
*/
|
|
37
|
-
async resolveParagonThemeUrlsFromConfig() {
|
|
38
|
-
try {
|
|
39
|
-
this.paragonThemeUrlsConfig = JSON.parse(process.env.PARAGON_THEME_URLS ?? '{}');
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
console.info('Paragon Plugin cannot load PARAGON_THEME_URLS env variable, skipping.');
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Generates `PARAGON_THEME` global variable in HTML document.
|
|
47
|
-
* @param {Object} compilation Webpack compilation object.
|
|
48
|
-
*/
|
|
49
|
-
injectParagonMetadataIntoDocument(compilation) {
|
|
50
|
-
const paragonMetadata = (0, utils_1.injectMetadataIntoDocument)(compilation, {
|
|
51
|
-
paragonThemeCss,
|
|
52
|
-
paragonVersion,
|
|
53
|
-
brandThemeCss,
|
|
54
|
-
brandVersion,
|
|
55
|
-
});
|
|
56
|
-
if (paragonMetadata) {
|
|
57
|
-
this.paragonMetadata = paragonMetadata;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
injectParagonStylesheetsIntoDocument(compilation) {
|
|
61
|
-
const file = compilation.getAsset('index.html');
|
|
62
|
-
// If the `index.html` hasn't loaded yet, or there are no Paragon theme URLs, then there is nothing to do yet.
|
|
63
|
-
if (!file || Object.keys(this.paragonThemeUrlsConfig || {}).length === 0) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
// Generates `<link rel="preload" as="style">` element(s) for the Paragon and brand CSS files.
|
|
67
|
-
const paragonStylesheetUrls = (0, utils_1.getParagonStylesheetUrls)({
|
|
68
|
-
paragonThemeUrls: this.paragonThemeUrlsConfig,
|
|
69
|
-
paragonVersion,
|
|
70
|
-
brandVersion,
|
|
71
|
-
});
|
|
72
|
-
const { core: paragonCoreCss, variants: paragonThemeVariantCss, } = paragonStylesheetUrls;
|
|
73
|
-
// We do not expect to have a Buffer here, ever.
|
|
74
|
-
const originalSource = file.source.source();
|
|
75
|
-
// Inject core CSS
|
|
76
|
-
let newSource = (0, utils_1.injectParagonCoreStylesheets)({
|
|
77
|
-
source: originalSource,
|
|
78
|
-
paragonCoreCss,
|
|
79
|
-
paragonThemeCss,
|
|
80
|
-
brandThemeCss,
|
|
81
|
-
});
|
|
82
|
-
// Inject theme variant CSS
|
|
83
|
-
newSource = (0, utils_1.injectParagonThemeVariantStylesheets)({
|
|
84
|
-
// @ts-expect-error newSource is possibly undefined here.
|
|
85
|
-
source: newSource.source(),
|
|
86
|
-
paragonThemeVariantCss,
|
|
87
|
-
paragonThemeCss,
|
|
88
|
-
brandThemeCss,
|
|
89
|
-
});
|
|
90
|
-
// @ts-expect-error newSource is possibly undefined here.
|
|
91
|
-
compilation.updateAsset('index.html', new webpack_1.sources.RawSource(newSource.source()));
|
|
92
|
-
}
|
|
93
|
-
apply(compiler) {
|
|
94
|
-
compiler.hooks.thisCompilation.tap(this.pluginName, (compilation) => {
|
|
95
|
-
compilation.hooks.processAssets.tap({
|
|
96
|
-
name: this.pluginName,
|
|
97
|
-
stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
|
|
98
|
-
additionalAssets: true,
|
|
99
|
-
}, () => {
|
|
100
|
-
// Iterate through each configured handler, passing the compilation to each.
|
|
101
|
-
this.processAssetsHandlers.forEach(async (handler) => {
|
|
102
|
-
await handler(compilation);
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
exports.default = ParagonWebpackPlugin;
|
|
@@ -1,7 +0,0 @@
|
|
|
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 ParagonWebpackPlugin_1 = __importDefault(require("./ParagonWebpackPlugin"));
|
|
7
|
-
exports.default = ParagonWebpackPlugin_1.default;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.findCoreCssAsset = findCoreCssAsset;
|
|
4
|
-
exports.findThemeVariantCssAssets = findThemeVariantCssAssets;
|
|
5
|
-
exports.getCssAssetsFromCompilation = getCssAssetsFromCompilation;
|
|
6
|
-
/**
|
|
7
|
-
* Finds the core CSS asset from the given array of Paragon assets.
|
|
8
|
-
*
|
|
9
|
-
* @param {Array} paragonAssets - An array of Paragon assets.
|
|
10
|
-
* @return {Object|undefined} The core CSS asset, or undefined if not found.
|
|
11
|
-
*/
|
|
12
|
-
function findCoreCssAsset(paragonAssets) {
|
|
13
|
-
return paragonAssets?.find((asset) => asset.name.includes('core') && asset.name.endsWith('.css'));
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Finds the theme variant CSS assets from the given Paragon assets based on the provided options.
|
|
17
|
-
*
|
|
18
|
-
* @param {Array} paragonAssets - An array of Paragon assets.
|
|
19
|
-
* @param {Object} options - The options for finding the theme variant CSS assets.
|
|
20
|
-
* @param {boolean} [options.isBrandOverride=false] - Indicates if the theme variant is a brand override.
|
|
21
|
-
* @param {Object} [options.brandThemeCss] - The brand theme CSS object.
|
|
22
|
-
* @param {Object} [options.paragonThemeCss] - The Paragon theme CSS object.
|
|
23
|
-
* @return {Object} - The theme variant CSS assets.
|
|
24
|
-
*/
|
|
25
|
-
function findThemeVariantCssAssets(paragonAssets, { isBrandOverride = false, brandThemeCss, paragonThemeCss, }) {
|
|
26
|
-
const themeVariantsSource = isBrandOverride ? brandThemeCss?.variants : paragonThemeCss?.variants;
|
|
27
|
-
const themeVariantCssAssets = {};
|
|
28
|
-
Object.entries(themeVariantsSource || {}).forEach(([themeVariant, value]) => {
|
|
29
|
-
const foundThemeVariantAsset = paragonAssets.find((asset) => asset.name.includes(value.outputChunkName));
|
|
30
|
-
if (!foundThemeVariantAsset) {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
themeVariantCssAssets[themeVariant] = {
|
|
34
|
-
fileName: foundThemeVariantAsset.name,
|
|
35
|
-
};
|
|
36
|
-
});
|
|
37
|
-
return themeVariantCssAssets;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Retrieves the CSS assets from the compilation based on the provided options.
|
|
41
|
-
*
|
|
42
|
-
* @param {Object} compilation - The compilation object.
|
|
43
|
-
* @param {Object} options - The options for retrieving the CSS assets.
|
|
44
|
-
* @param {boolean} [options.isBrandOverride=false] - Indicates if the assets are for a brand override.
|
|
45
|
-
* @param {Object} [options.brandThemeCss] - The brand theme CSS object.
|
|
46
|
-
* @param {Object} [options.paragonThemeCss] - The Paragon theme CSS object.
|
|
47
|
-
* @return {Object} - The CSS assets, including the core CSS asset and theme variant CSS assets.
|
|
48
|
-
*/
|
|
49
|
-
function getCssAssetsFromCompilation(compilation, { isBrandOverride = false, brandThemeCss, paragonThemeCss, }) {
|
|
50
|
-
const assetSubstring = isBrandOverride ? 'brand' : 'paragon';
|
|
51
|
-
const paragonAssets = compilation.getAssets().filter(asset => asset.name.includes(assetSubstring) && asset.name.endsWith('.css'));
|
|
52
|
-
const coreCssAsset = findCoreCssAsset(paragonAssets);
|
|
53
|
-
const themeVariantCssAssets = findThemeVariantCssAssets(paragonAssets, {
|
|
54
|
-
isBrandOverride,
|
|
55
|
-
paragonThemeCss,
|
|
56
|
-
brandThemeCss,
|
|
57
|
-
});
|
|
58
|
-
return {
|
|
59
|
-
coreCssAsset: {
|
|
60
|
-
fileName: coreCssAsset?.name,
|
|
61
|
-
},
|
|
62
|
-
themeVariantCssAssets,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.injectMetadataIntoDocument = injectMetadataIntoDocument;
|
|
4
|
-
const webpack_1 = require("webpack");
|
|
5
|
-
const assetUtils_1 = require("./assetUtils");
|
|
6
|
-
const scriptUtils_1 = require("./scriptUtils");
|
|
7
|
-
/**
|
|
8
|
-
* Injects metadata into the HTML document by modifying the 'index.html' asset in the compilation.
|
|
9
|
-
*
|
|
10
|
-
* @param {Object} compilation - The Webpack compilation object.
|
|
11
|
-
* @param {Object} options - The options object.
|
|
12
|
-
* @param {Object} options.paragonThemeCss - The Paragon theme CSS object.
|
|
13
|
-
* @param {string} options.paragonVersion - The version of the Paragon theme.
|
|
14
|
-
* @param {Object} options.brandThemeCss - The brand theme CSS object.
|
|
15
|
-
* @param {string} options.brandVersion - The version of the brand theme.
|
|
16
|
-
* @return {Object|undefined} The script contents object if the 'index.html' asset exists, otherwise undefined.
|
|
17
|
-
*/
|
|
18
|
-
function injectMetadataIntoDocument(compilation, { paragonThemeCss, paragonVersion, brandThemeCss, brandVersion, }) {
|
|
19
|
-
const file = compilation.getAsset('index.html');
|
|
20
|
-
if (!file) {
|
|
21
|
-
return undefined;
|
|
22
|
-
}
|
|
23
|
-
const { coreCssAsset: paragonCoreCssAsset, themeVariantCssAssets: paragonThemeVariantCssAssets, } = (0, assetUtils_1.getCssAssetsFromCompilation)(compilation, {
|
|
24
|
-
brandThemeCss,
|
|
25
|
-
paragonThemeCss,
|
|
26
|
-
});
|
|
27
|
-
const { coreCssAsset: brandCoreCssAsset, themeVariantCssAssets: brandThemeVariantCssAssets, } = (0, assetUtils_1.getCssAssetsFromCompilation)(compilation, {
|
|
28
|
-
isBrandOverride: true,
|
|
29
|
-
brandThemeCss,
|
|
30
|
-
paragonThemeCss,
|
|
31
|
-
});
|
|
32
|
-
const scriptContents = (0, scriptUtils_1.generateScriptContents)({
|
|
33
|
-
paragonCoreCssAsset,
|
|
34
|
-
paragonThemeVariantCssAssets,
|
|
35
|
-
brandCoreCssAsset,
|
|
36
|
-
brandThemeVariantCssAssets,
|
|
37
|
-
paragonThemeCss,
|
|
38
|
-
paragonVersion,
|
|
39
|
-
brandThemeCss,
|
|
40
|
-
brandVersion,
|
|
41
|
-
});
|
|
42
|
-
// We expect this to be a string at all times.
|
|
43
|
-
const originalSource = file.source.source();
|
|
44
|
-
const newSource = (0, scriptUtils_1.insertScriptContentsIntoDocument)({
|
|
45
|
-
originalSource,
|
|
46
|
-
// @ts-expect-error This parameter doesn't exist in the function.
|
|
47
|
-
coreCssAsset: paragonCoreCssAsset,
|
|
48
|
-
themeVariantCssAssets: paragonThemeVariantCssAssets,
|
|
49
|
-
scriptContents,
|
|
50
|
-
});
|
|
51
|
-
compilation.updateAsset('index.html', new webpack_1.sources.RawSource(newSource.source()));
|
|
52
|
-
return scriptContents;
|
|
53
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.injectParagonThemeVariantStylesheets = exports.injectParagonCoreStylesheets = exports.getParagonStylesheetUrls = exports.injectMetadataIntoDocument = void 0;
|
|
4
|
-
var htmlUtils_1 = require("./htmlUtils");
|
|
5
|
-
Object.defineProperty(exports, "injectMetadataIntoDocument", { enumerable: true, get: function () { return htmlUtils_1.injectMetadataIntoDocument; } });
|
|
6
|
-
var paragonStylesheetUtils_1 = require("./paragonStylesheetUtils");
|
|
7
|
-
Object.defineProperty(exports, "getParagonStylesheetUrls", { enumerable: true, get: function () { return paragonStylesheetUtils_1.getParagonStylesheetUrls; } });
|
|
8
|
-
Object.defineProperty(exports, "injectParagonCoreStylesheets", { enumerable: true, get: function () { return paragonStylesheetUtils_1.injectParagonCoreStylesheets; } });
|
|
9
|
-
Object.defineProperty(exports, "injectParagonThemeVariantStylesheets", { enumerable: true, get: function () { return paragonStylesheetUtils_1.injectParagonThemeVariantStylesheets; } });
|