@redhat-cloud-services/frontend-components-config 4.5.12 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/fec.js CHANGED
@@ -3,6 +3,9 @@ const { execSync } = require('child_process');
3
3
  const static = require('@redhat-cloud-services/frontend-components-config-utilities/serve-federated');
4
4
  const yargs = require('yargs');
5
5
 
6
+ const devScript = require('../src/scripts/dev-script');
7
+ const { logError } = require('../src/scripts/common')
8
+
6
9
  function patchHosts() {
7
10
  const command = `
8
11
  for host in prod.foo.redhat.com stage.foo.redhat.com qa.foo.redhat.com ci.foo.redhat.com
@@ -15,7 +18,11 @@ do
15
18
  fi
16
19
  done
17
20
  `
18
- execSync(command)
21
+ try {
22
+ execSync(command)
23
+ } catch (error) {
24
+ logError('Unable to patch /etc/hosts! Please to run the script as sudo.')
25
+ }
19
26
  }
20
27
 
21
28
  const cwd = process.cwd();
@@ -35,12 +42,19 @@ const argv = yargs
35
42
  });
36
43
  })
37
44
  .command('patch-etc-hosts', 'You may have to run this as \'sudo\'. Setup your etc/hosts allow development hosts in your browser')
45
+ .command('dev', 'Start development server', (yargs) => {
46
+ yargs.positional('webpack-config', {
47
+ type: 'string',
48
+ describe: 'Path to webpack config',
49
+ })
50
+ })
38
51
  .help()
39
52
  .argv;
40
53
 
41
54
  const scripts = {
42
55
  static,
43
- 'patch-etc-hosts': patchHosts
56
+ 'patch-etc-hosts': patchHosts,
57
+ dev: devScript
44
58
  };
45
59
 
46
60
  const args = [ argv, cwd ];
package/index.js CHANGED
@@ -33,7 +33,13 @@ module.exports = (configurations) => {
33
33
  configurations.isProd = configurations.isProd || process.env.NODE_ENV === 'production';
34
34
  const isProd = configurations.isProd;
35
35
  const { insights } = require(`${configurations.rootFolder}/package.json`);
36
- const gitBranch = process.env.TRAVIS_BRANCH || process.env.BRANCH || gitRevisionPlugin.branch();
36
+ let gitBranch;
37
+ try {
38
+ gitBranch = process.env.TRAVIS_BRANCH || process.env.BRANCH || gitRevisionPlugin.branch();
39
+ } catch (error) {
40
+ console.log('[fec] no git branch detected, using main for webpack "main" config.');
41
+ gitBranch = 'main';
42
+ }
37
43
  const appDeployment = configurations.deployment || (isProd && betaBranches.includes(gitBranch) ? 'beta/apps' : 'apps');
38
44
 
39
45
  const publicPath = `/${appDeployment}/${insights.appname}/`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redhat-cloud-services/frontend-components-config",
3
- "version": "4.5.12",
3
+ "version": "4.6.0",
4
4
  "description": "Config plugins and settings for RedHat Cloud Services project.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -22,12 +22,15 @@
22
22
  "dependencies": {
23
23
  "@redhat-cloud-services/frontend-components-config-utilities": "^1.5.9",
24
24
  "assert": "^2.0.0",
25
+ "axios": "^0.25.0",
25
26
  "babel-loader": "^8.2.2",
26
27
  "browserify-zlib": "^0.2.0",
27
28
  "buffer": "^6.0.3",
28
29
  "clean-webpack-plugin": "^3.0.0",
29
30
  "css-loader": "^5.2.6",
30
31
  "concurrently": "^6.3.0",
32
+ "chalk": "^5.0.0",
33
+ "express": "^4.17.2",
31
34
  "git-revision-webpack-plugin": "^3.0.6",
32
35
  "glob": "^7.0.0",
33
36
  "html-replace-webpack-plugin": "^2.6.0",
@@ -35,8 +38,10 @@
35
38
  "https-proxy-agent": "^5.0.0",
36
39
  "http-server": "^13.0.2",
37
40
  "mini-css-extract-plugin": "^1.6.0",
41
+ "inquirer": "^8.2.0",
38
42
  "js-yaml": "^4.0.0",
39
43
  "jws": "^4.0.0",
44
+ "lodash": "^4.17.21",
40
45
  "path-browserify": "^1.0.1",
41
46
  "process": "^0.11.10",
42
47
  "sass": "^1.34.1",
@@ -0,0 +1,7 @@
1
+ const chalk = require('chalk');
2
+
3
+ function logError(message) {
4
+ console.log(chalk.blue('[fec]') + chalk.red(' ERROR: ') + message);
5
+ }
6
+
7
+ module.exports.logError = logError;
@@ -0,0 +1,70 @@
1
+ const path = require('path');
2
+ const express = require('express');
3
+ const axios = require('axios');
4
+ const jsVarName = require('@redhat-cloud-services/frontend-components-config-utilities/jsVarName');
5
+ const fs = require('fs');
6
+ const jsyaml = require('js-yaml');
7
+
8
+ const cwd = process.cwd();
9
+ const pgk = require(path.resolve(cwd, './package.json'));
10
+
11
+ const appname = jsVarName(pgk.insights.appname);
12
+ const moduleName = jsVarName(appname);
13
+
14
+ const frontendDeployConfig = jsyaml.load(fs.readFileSync(path.resolve(cwd, './deploy/frontend.yaml')));
15
+ const frontendSpec = frontendDeployConfig.objects[0];
16
+ const navItems = frontendSpec.spec.navItems;
17
+ const fecModules = frontendSpec.spec.module;
18
+ const bundles = Array.from(
19
+ new Set(
20
+ fecModules.modules
21
+ .map(({ routes }) => routes)
22
+ .flat()
23
+ .map(({ pathname }) => pathname.split('/')[1])
24
+ )
25
+ );
26
+
27
+ const app = express();
28
+ const port = 9999;
29
+
30
+ const BASE_URL = 'https://raw.githubusercontent.com/RedHatInsights/cloud-services-config/ci-beta/';
31
+
32
+ function getRequestBundle(requestUrl) {
33
+ const bundle = requestUrl.split('/').pop().split('-').shift();
34
+ return bundle === 'rhel' ? 'insights' : bundle;
35
+ }
36
+
37
+ app.get('*', async (req, res, next) => {
38
+ let requestUrl = `${BASE_URL}${req.url.replace(/(\/beta)?\/config/gm, '')}`;
39
+ if (requestUrl.includes('insights-navigation.json')) {
40
+ requestUrl = requestUrl.replace('insights-navigation.json', 'rhel-navigation.json');
41
+ }
42
+ try {
43
+ const schema = await axios.get(requestUrl);
44
+ if (req.url.includes('-navigation.json') && bundles.some((bundle) => req.url.includes(bundle))) {
45
+ const requestBundle = getRequestBundle(requestUrl);
46
+ /** handle nav json */
47
+ const payload = schema.data;
48
+ payload.navItems = [...payload.navItems, ...navItems.filter(({ href }) => href.includes(requestBundle))];
49
+ res.json(payload);
50
+ res.end();
51
+ return;
52
+ } else if (req.url.includes('fed-modules.json')) {
53
+ /** handle fed-modules */
54
+ const payload = schema.data;
55
+ payload[moduleName] = fecModules;
56
+ res.json(payload);
57
+ res.end();
58
+ return;
59
+ }
60
+ res.json(schema.data);
61
+ res.end();
62
+ } catch (error) {
63
+ console.log(error);
64
+ next(error);
65
+ }
66
+ });
67
+
68
+ app.listen(port, () => {
69
+ console.log('csc-intercept-server is running on port ' + port);
70
+ });
@@ -0,0 +1,102 @@
1
+ /* eslint-disable no-console */
2
+ const inquirer = require('inquirer');
3
+ const { resolve } = require('path');
4
+ const { statSync } = require('fs');
5
+ const { spawn } = require('child_process');
6
+ const { logError } = require('./common');
7
+
8
+ async function setEnv(cwd) {
9
+ return inquirer
10
+ .prompt([
11
+ {
12
+ type: 'list',
13
+ name: 'clouddotEnv',
14
+ message: 'Which platform environment you want to use?',
15
+ choices: ['stage', 'prod', { value: 'qa', name: 'qa (deprecated)' }, { value: 'ci', name: 'ci (deprecated)' }],
16
+ },
17
+ {
18
+ type: 'list',
19
+ name: 'uiEnv',
20
+ message: 'Which Chrome environment you want to use?',
21
+ choices: ['beta', 'stable'],
22
+ },
23
+ ])
24
+ .then((answers) => {
25
+ const { uiEnv, clouddotEnv } = answers;
26
+ process.env.BETA = uiEnv === 'beta' ? 'true' : 'false';
27
+ process.env.CLOUDOT_ENV = clouddotEnv ? clouddotEnv : 'stage';
28
+ process.env.FEC_ROOT_DIR = cwd;
29
+ });
30
+ }
31
+
32
+ function getWebpackConfigPath(path, cwd) {
33
+ let configPath;
34
+ try {
35
+ configPath = resolve(cwd, path);
36
+ statSync(configPath);
37
+ let config = require(configPath);
38
+ if (typeof config === 'function') {
39
+ config = config(process.env);
40
+ }
41
+ return configPath;
42
+ } catch (error) {
43
+ if (configPath) {
44
+ logError(`Unable to open webpack config at: "${configPath}"`);
45
+ } else {
46
+ logError(error);
47
+ throw 'FEC binary failed';
48
+ }
49
+ }
50
+ }
51
+
52
+ function validateFECConfig(cwd) {
53
+ const configPath = resolve(cwd, './fec.config.js');
54
+ try {
55
+ statSync(configPath);
56
+ } catch (error) {
57
+ logError(`Unable to locate "fec.config.js" at ${configPath}`);
58
+ throw 'fec.config.js validation failed, file does not exist';
59
+ }
60
+
61
+ const config = require(configPath);
62
+ if (!config.appUrl) {
63
+ logError('Missing config "appUrl" in fec.config.js');
64
+ throw 'fec.config.js validation failed, missing "appUrl" config';
65
+ }
66
+ process.env.FEC_CONFIG_PATH = configPath;
67
+ }
68
+
69
+ async function devScript(argv, cwd) {
70
+ try {
71
+ validateFECConfig(cwd);
72
+
73
+ const fecConfig = require(process.env.FEC_CONFIG_PATH);
74
+ const processArgs = [];
75
+ let configPath;
76
+ if (typeof argv.webpackConfig !== 'undefined') {
77
+ configPath = getWebpackConfigPath(argv.webpackConfig, cwd);
78
+ } else {
79
+ configPath = resolve(__dirname, './dev.webpack.config.js');
80
+ }
81
+ processArgs.push(`node_modules/.bin/webpack serve -c ${configPath}`);
82
+ await setEnv(cwd);
83
+ spawn('node', processArgs, {
84
+ stdio: [process.stdout, process.stdout, process.stdout],
85
+ cwd,
86
+ shell: true,
87
+ });
88
+ if (fecConfig.interceptChromeConfig === true) {
89
+ const interceptorServerPath = resolve(__dirname, './csc-interceptor-server.js');
90
+ const interceptorServerArgs = [interceptorServerPath];
91
+ spawn('node', interceptorServerArgs, {
92
+ stdio: [process.stdout, process.stdout, process.stdout],
93
+ cwd,
94
+ shell: true,
95
+ });
96
+ }
97
+ } catch (error) {
98
+ process.exit(1);
99
+ }
100
+ }
101
+
102
+ module.exports = devScript;
@@ -0,0 +1,62 @@
1
+ const config = require('@redhat-cloud-services/frontend-components-config');
2
+ const commonPlugins = require('./webpack.plugins.js');
3
+ const fecConfig = require(process.env.FEC_CONFIG_PATH);
4
+
5
+ const isBeta = process.env.BETA === 'true';
6
+
7
+ function parseRegexpURL(url) {
8
+ return new RegExp(`${isBeta ? '/beta' : ''}${url.toString()}`);
9
+ }
10
+
11
+ function createAppUrl(appUrl) {
12
+ if (Array.isArray(appUrl)) {
13
+ return appUrl.map((url) => {
14
+ if (typeof url === 'object') {
15
+ return parseRegexpURL(url);
16
+ } else if (typeof url === 'string') {
17
+ return `${isBeta ? '/beta' : ''}${url}`;
18
+ } else {
19
+ throw `Invalid appURL format! Expected string or regexp, got ${typeof url}. Check your fec.config.js:appUrl.`;
20
+ }
21
+ });
22
+ } else if (typeof appUrl === 'object') {
23
+ return parseRegexpURL(appUrl);
24
+ } else if (typeof appUrl === 'string') {
25
+ return `${isBeta ? '/beta' : ''}${appUrl}`;
26
+ } else {
27
+ throw `Invalid appURL format! Expected string or regexp, got ${typeof appUrl}. Check your fec.config.js:appUrl.`;
28
+ }
29
+ }
30
+
31
+ const appUrl = createAppUrl(fecConfig.appUrl);
32
+
33
+ const { plugins: externalPlugins, interceptChromeConfig, routes, ...externalConfig } = fecConfig;
34
+
35
+ const internalProxyRoutes = {
36
+ ...routes,
37
+ ...(interceptChromeConfig === true
38
+ ? {
39
+ '/beta/config': {
40
+ host: 'http://localhost:9999',
41
+ },
42
+ '/config': {
43
+ host: 'http://localhost:9999',
44
+ },
45
+ }
46
+ : {}),
47
+ };
48
+
49
+ const { config: webpackConfig, plugins } = config({
50
+ ...externalConfig,
51
+ routes: internalProxyRoutes,
52
+ appUrl,
53
+ deployment: isBeta ? 'beta/apps' : 'apps',
54
+ env: `${process.env.CLOUDOT_ENV}-${isBeta === 'true' ? 'beta' : 'stable'}`,
55
+ rootFolder: process.env.FEC_ROOT_DIR || process.cwd(),
56
+ });
57
+ plugins.push(...commonPlugins, ...externalPlugins);
58
+
59
+ module.exports = {
60
+ ...webpackConfig,
61
+ plugins,
62
+ };
@@ -0,0 +1,2 @@
1
+ // Used as an empty module to save bundle size
2
+ module.exports = {};
@@ -0,0 +1,19 @@
1
+ const config = require('@redhat-cloud-services/frontend-components-config');
2
+ const commonPlugins = require('./webpack.plugins');
3
+ const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
4
+
5
+ const { config: webpackConfig, plugins } = config({
6
+ rootFolder: process.env.FEC_ROOT_DIR || process.cwd(),
7
+ ...(process.env.BETA === 'true' && { deployment: 'beta/apps' }),
8
+ });
9
+ plugins.push(...commonPlugins);
10
+
11
+ module.exports = (env) => {
12
+ if (env && env.analyze === 'true') {
13
+ plugins.push(new BundleAnalyzerPlugin());
14
+ }
15
+ return {
16
+ ...webpackConfig,
17
+ plugins,
18
+ };
19
+ };
@@ -0,0 +1,14 @@
1
+ const webpack = require('webpack');
2
+ const { resolve } = require('path');
3
+ const fedModulePlugin = require('@redhat-cloud-services/frontend-components-config/federated-modules');
4
+
5
+ const rootDir = process.env.FEC_ROOT_DIR || process.cwd();
6
+
7
+ const plugins = [fedModulePlugin({ root: rootDir })];
8
+
9
+ // Save 20kb of bundle size in prod
10
+ if (process.env.NODE_ENV === 'production') {
11
+ plugins.push(new webpack.NormalModuleReplacementPlugin(/redux-logger/, resolve(__dirname, './empty.js')));
12
+ }
13
+
14
+ module.exports = plugins;