@redhat-cloud-services/frontend-components-config 4.5.10 → 4.6.1

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/README.md CHANGED
@@ -340,6 +340,9 @@ Use binary in your `package.json` scripts section:
340
340
  }
341
341
  ```
342
342
 
343
+ ## Patch etc hosts
344
+ This is a required step for first time setup. It will allow your localhost to map to [env].foo.redhat.com. This is required to run only once on your machine. **Your OS may require running the script as sudo**!
345
+
343
346
  ## Static
344
347
 
345
348
  A script that will run webpack build and serve webpack output through `http-serve` server. **This is not supposed to replace webpack dev server!**
package/bin/fec.js CHANGED
@@ -1,8 +1,30 @@
1
1
  #!/usr/bin/env node
2
-
2
+ 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
+
9
+ function patchHosts() {
10
+ const command = `
11
+ for host in prod.foo.redhat.com stage.foo.redhat.com qa.foo.redhat.com ci.foo.redhat.com
12
+ do
13
+ grep -q $host /etc/hosts 2>/dev/null
14
+ if [ $? -ne 0 ]
15
+ then
16
+ echo "Adding $host to /etc/hosts"
17
+ echo "127.0.0.1 $host" >>/etc/hosts
18
+ fi
19
+ done
20
+ `
21
+ try {
22
+ execSync(command)
23
+ } catch (error) {
24
+ logError('Unable to patch /etc/hosts! Please to run the script as sudo.')
25
+ }
26
+ }
27
+
6
28
  const cwd = process.cwd();
7
29
 
8
30
  const argv = yargs
@@ -19,11 +41,20 @@ const argv = yargs
19
41
  default: 8003
20
42
  });
21
43
  })
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
+ })
22
51
  .help()
23
52
  .argv;
24
53
 
25
54
  const scripts = {
26
- static
55
+ static,
56
+ 'patch-etc-hosts': patchHosts,
57
+ dev: devScript
27
58
  };
28
59
 
29
60
  const args = [ argv, cwd ];
package/index.js CHANGED
@@ -2,81 +2,85 @@ const config = require('./src/config');
2
2
  const plugins = require('./src/plugins');
3
3
  const { sync } = require('glob');
4
4
 
5
- const gitRevisionPlugin = new(require('git-revision-webpack-plugin'))({
6
- branch: true
5
+ const gitRevisionPlugin = new (require('git-revision-webpack-plugin'))({
6
+ branch: true,
7
7
  });
8
- const betaBranches = [ 'master', 'qa-beta', 'ci-beta', 'prod-beta', 'main', 'devel', 'stage-beta' ];
9
- const akamaiBranches = [ 'prod-beta', 'prod-stable' ];
8
+ const betaBranches = ['master', 'qa-beta', 'ci-beta', 'prod-beta', 'main', 'devel', 'stage-beta'];
9
+ const akamaiBranches = ['prod-beta', 'prod-stable'];
10
10
 
11
11
  const getAppEntry = (rootFolder, isProd) => {
12
- // Use entry-dev if it exists
13
- if (!isProd) {
14
- const entries = sync('src/entry-dev.{js,jsx,ts,tsx}', { cwd: rootFolder });
15
- if (entries.length > 1) {
16
- console.warn('Found multiple entry-dev files. Using', entries[0]);
17
- }
18
-
19
- if (entries.length > 0) {
20
- return `${rootFolder}/${entries[0]}`;
21
- }
12
+ // Use entry-dev if it exists
13
+ if (!isProd) {
14
+ const entries = sync('src/entry-dev.{js,jsx,ts,tsx}', { cwd: rootFolder });
15
+ if (entries.length > 1) {
16
+ console.warn('Found multiple entry-dev files. Using', entries[0]);
22
17
  }
23
18
 
24
- const entries = sync('src/entry.{js,jsx,ts,tsx}', { cwd: rootFolder });
25
- if (entries.length > 1) {
26
- console.warn('Found multiple entry files. Using', entries[0]);
19
+ if (entries.length > 0) {
20
+ return `${rootFolder}/${entries[0]}`;
27
21
  }
22
+ }
28
23
 
29
- return `${rootFolder}/${entries[0]}`;
24
+ const entries = sync('src/entry.{js,jsx,ts,tsx}', { cwd: rootFolder });
25
+ if (entries.length > 1) {
26
+ console.warn('Found multiple entry files. Using', entries[0]);
27
+ }
28
+
29
+ return `${rootFolder}/${entries[0]}`;
30
30
  };
31
31
 
32
32
  module.exports = (configurations) => {
33
- configurations.isProd = configurations.isProd || process.env.NODE_ENV === 'production';
34
- const isProd = configurations.isProd;
35
- const { insights } = require(`${configurations.rootFolder}/package.json`);
36
- const gitBranch = process.env.TRAVIS_BRANCH || process.env.BRANCH || gitRevisionPlugin.branch();
37
- const appDeployment = configurations.deployment || ((isProd && betaBranches.includes(gitBranch)) ?
38
- 'beta/apps' :
39
- 'apps');
40
-
41
- const publicPath = `/${appDeployment}/${insights.appname}/`;
42
- const appEntry = configurations.appEntry || getAppEntry(configurations.rootFolder, isProd);
43
- const generateSourceMaps = !akamaiBranches.includes(gitBranch);
33
+ configurations.isProd = configurations.isProd || process.env.NODE_ENV === 'production';
34
+ const isProd = configurations.isProd;
35
+ const { insights } = require(`${configurations.rootFolder}/package.json`);
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
+ }
43
+ const appDeployment = configurations.deployment || (isProd && betaBranches.includes(gitBranch) ? 'beta/apps' : 'apps');
44
44
 
45
- if (configurations.debug) {
46
- /* eslint-disable no-console */
47
- console.log('~~~Using variables~~~');
48
- console.log(`Root folder: ${configurations.rootFolder}`);
49
- console.log(`Current branch: ${gitBranch}`);
50
- !generateSourceMaps && console.log(`Source map generation for "${gitBranch}" deployment has been disabled.`);
51
- console.log(`Beta branches: ${betaBranches}`);
52
- console.log(`Using deployments: ${appDeployment}`);
53
- console.log(`Public path: ${publicPath}`);
54
- console.log(`App entry: ${appEntry}`);
55
- console.log(`Use proxy: ${configurations.useProxy ? 'true' : 'false'}`);
56
- if (!(configurations.useProxy || configurations.standalone)) {
57
- console.warn('Insights-proxy is deprecated in favor of "useProxy" or "standalone".');
58
- console.warn('See https://github.com/RedHatInsights/frontend-components/blob/master/packages/config/README.md');
59
- }
45
+ const publicPath = `/${appDeployment}/${insights.appname}/`;
46
+ const appEntry = configurations.appEntry || getAppEntry(configurations.rootFolder, isProd);
47
+ const generateSourceMaps = !akamaiBranches.includes(gitBranch);
60
48
 
61
- console.log('~~~~~~~~~~~~~~~~~~~~~');
62
- /* eslint-enable no-console */
49
+ if (configurations.debug) {
50
+ /* eslint-disable no-console */
51
+ console.log('~~~Using variables~~~');
52
+ console.log(`Root folder: ${configurations.rootFolder}`);
53
+ console.log(`Current branch: ${gitBranch}`);
54
+ !generateSourceMaps && console.log(`Source map generation for "${gitBranch}" deployment has been disabled.`);
55
+ console.log(`Beta branches: ${betaBranches}`);
56
+ console.log(`Using deployments: ${appDeployment}`);
57
+ console.log(`Public path: ${publicPath}`);
58
+ console.log(`App entry: ${appEntry}`);
59
+ console.log(`Use proxy: ${configurations.useProxy ? 'true' : 'false'}`);
60
+ if (!(configurations.useProxy || configurations.standalone)) {
61
+ console.warn('Insights-proxy is deprecated in favor of "useProxy" or "standalone".');
62
+ console.warn('See https://github.com/RedHatInsights/frontend-components/blob/master/packages/config/README.md');
63
63
  }
64
64
 
65
- return {
66
- config: config({
67
- ...configurations,
68
- appDeployment,
69
- insights,
70
- publicPath,
71
- appEntry,
72
- appName: insights.appname
73
- }),
74
- plugins: plugins({
75
- ...configurations,
76
- generateSourceMaps,
77
- appDeployment,
78
- insights,
79
- publicPath
80
- })
81
- };
65
+ console.log('~~~~~~~~~~~~~~~~~~~~~');
66
+ /* eslint-enable no-console */
67
+ }
68
+
69
+ return {
70
+ config: config({
71
+ ...configurations,
72
+ appDeployment,
73
+ insights,
74
+ publicPath,
75
+ appEntry,
76
+ appName: insights.appname,
77
+ }),
78
+ plugins: plugins({
79
+ ...configurations,
80
+ generateSourceMaps,
81
+ appDeployment,
82
+ insights,
83
+ publicPath,
84
+ }),
85
+ };
82
86
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redhat-cloud-services/frontend-components-config",
3
- "version": "4.5.10",
3
+ "version": "4.6.1",
4
4
  "description": "Config plugins and settings for RedHat Cloud Services project.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -20,14 +20,17 @@
20
20
  },
21
21
  "homepage": "https://github.com/RedHatInsights/frontend-components/tree/master/packages/config#readme",
22
22
  "dependencies": {
23
- "@redhat-cloud-services/frontend-components-config-utilities": "^1.5.8",
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": "^4.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",
package/src/config.js CHANGED
@@ -6,192 +6,198 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
6
6
  const searchIgnoredStyles = require('@redhat-cloud-services/frontend-components-config-utilities/search-ignored-styles');
7
7
 
8
8
  module.exports = ({
9
- port,
10
- publicPath,
11
- appEntry,
12
- rootFolder,
13
- https,
14
- mode,
15
- appName,
16
- useFileHash = true,
17
- betaEnv,
18
- env,
19
- sassPrefix,
20
- skipChrome2 = false,
21
- useProxy,
22
- proxyURL,
23
- localChrome,
24
- keycloakUri,
25
- customProxy,
26
- routes,
27
- routesPath,
28
- isProd,
29
- standalone = false,
30
- reposDir,
31
- appUrl = [],
32
- proxyVerbose,
33
- useCloud,
34
- target,
35
- registry,
36
- client = {},
37
- bundlePfModules = false,
38
- useChromeTemplate = false
9
+ port,
10
+ publicPath,
11
+ appEntry,
12
+ rootFolder,
13
+ https,
14
+ mode,
15
+ appName,
16
+ useFileHash = true,
17
+ betaEnv,
18
+ env,
19
+ sassPrefix,
20
+ skipChrome2 = false,
21
+ useProxy,
22
+ proxyURL,
23
+ localChrome,
24
+ keycloakUri,
25
+ customProxy,
26
+ routes,
27
+ routesPath,
28
+ isProd,
29
+ standalone = false,
30
+ reposDir,
31
+ appUrl = [],
32
+ proxyVerbose,
33
+ useCloud,
34
+ target,
35
+ registry,
36
+ client = {},
37
+ bundlePfModules = false,
38
+ useChromeTemplate = false,
39
39
  } = {}) => {
40
- const filenameMask = `js/[name]${useFileHash ? `.${Date.now()}.[fullhash]` : ''}.js`;
41
- if (betaEnv) {
42
- env = `${betaEnv}-beta`;
43
- console.warn('betaEnv is deprecated in favor of env');
44
- }
40
+ const filenameMask = `js/[name]${useFileHash ? `.${Date.now()}.[fullhash]` : ''}.js`;
41
+ if (betaEnv) {
42
+ env = `${betaEnv}-beta`;
43
+ console.warn('betaEnv is deprecated in favor of env');
44
+ }
45
45
 
46
- const outputPath = `${rootFolder || ''}/dist`;
46
+ const outputPath = `${rootFolder || ''}/dist`;
47
47
 
48
- const copyTemplate = (chromePath) => {
49
- const template = fs.readFileSync(`${chromePath}/index.html`, { encoding: 'utf-8' });
50
- if (!fs.existsSync(outputPath)) {
51
- fs.mkdirSync(outputPath);
52
- }
48
+ const copyTemplate = (chromePath) => {
49
+ const template = fs.readFileSync(`${chromePath}/index.html`, { encoding: 'utf-8' });
50
+ if (!fs.existsSync(outputPath)) {
51
+ fs.mkdirSync(outputPath);
52
+ }
53
53
 
54
- fs.writeFileSync(`${outputPath}/index.html`, template);
55
- };
54
+ fs.writeFileSync(`${outputPath}/index.html`, template);
55
+ };
56
56
 
57
- const devServerPort = typeof port === 'number' ? port : useProxy || standalone ? 1337 : 8002;
58
- return {
59
- mode: mode || (isProd ? 'production' : 'development'),
60
- devtool: false,
61
- entry: {
62
- App: appEntry
57
+ const devServerPort = typeof port === 'number' ? port : useProxy || standalone ? 1337 : 8002;
58
+ return {
59
+ mode: mode || (isProd ? 'production' : 'development'),
60
+ devtool: false,
61
+ entry: {
62
+ App: appEntry,
63
+ },
64
+ output: {
65
+ filename: filenameMask,
66
+ path: outputPath,
67
+ publicPath,
68
+ chunkFilename: filenameMask,
69
+ },
70
+ module: {
71
+ rules: [
72
+ {
73
+ test: new RegExp(appEntry),
74
+ loader: path.resolve(__dirname, './chrome-render-loader.js'),
75
+ options: {
76
+ appName,
77
+ skipChrome2,
78
+ },
79
+ },
80
+ {
81
+ test: /src\/.*\.js$/,
82
+ exclude: /(node_modules|bower_components)/i,
83
+ use: ['babel-loader'],
63
84
  },
64
- output: {
65
- filename: filenameMask,
66
- path: outputPath,
67
- publicPath,
68
- chunkFilename: filenameMask
85
+ {
86
+ test: /src\/.*\.tsx?$/,
87
+ loader: 'ts-loader',
88
+ exclude: /(node_modules)/i,
69
89
  },
70
- module: {
71
- rules: [{
72
- test: new RegExp(appEntry),
73
- loader: path.resolve(__dirname, './chrome-render-loader.js'),
74
- options: {
75
- appName,
76
- skipChrome2
77
- }
78
- }, {
79
- test: /src\/.*\.js$/,
80
- exclude: /(node_modules|bower_components)/i,
81
- use: [ 'babel-loader' ]
82
- }, {
83
- test: /src\/.*\.tsx?$/,
84
- loader: 'ts-loader',
85
- exclude: /(node_modules)/i
86
- }, {
87
- test: /\.s?[ac]ss$/,
88
- use: [
89
- MiniCssExtractPlugin.loader,
90
- 'css-loader',
91
- {
92
- /**
93
- * Second sass loader used for scoping the css with class name.
94
- * Has to be included as second in order to re-scope already compiled sass files.
95
- * Second loader is required to avoid scoping mixins, includes and other sass partials. We want to only scope the CSS output.
96
- */
97
- loader: 'sass-loader',
98
- options: {
99
- additionalData: function(content, loaderContext) {
100
- const { resourcePath, rootContext } = loaderContext;
101
- const relativePath = path.relative(rootContext, resourcePath);
102
- /**
103
- * Add app class context for local style files.
104
- * Context class is equal to app name and that class ass added to root element via the chrome-render-loader.
105
- */
106
- if (relativePath.match(/^src/)) {
107
- return `${sassPrefix || `.${appName}`}{\n${content}\n}`;
108
- }
90
+ {
91
+ test: /\.s?[ac]ss$/,
92
+ use: [
93
+ MiniCssExtractPlugin.loader,
94
+ 'css-loader',
95
+ {
96
+ /**
97
+ * Second sass loader used for scoping the css with class name.
98
+ * Has to be included as second in order to re-scope already compiled sass files.
99
+ * Second loader is required to avoid scoping mixins, includes and other sass partials. We want to only scope the CSS output.
100
+ */
101
+ loader: 'sass-loader',
102
+ options: {
103
+ additionalData: function (content, loaderContext) {
104
+ const { resourcePath, rootContext } = loaderContext;
105
+ const relativePath = path.relative(rootContext, resourcePath);
106
+ /**
107
+ * Add app class context for local style files.
108
+ * Context class is equal to app name and that class ass added to root element via the chrome-render-loader.
109
+ */
110
+ if (relativePath.match(/^src/)) {
111
+ return `${sassPrefix || `.${appName}`}{\n${content}\n}`;
112
+ }
109
113
 
110
- return content;
111
- }
112
- }
113
- },
114
- 'sass-loader'
115
- ]
116
- }, {
117
- test: /\.(woff(2)?|ttf|jpg|png|eot|gif|svg)(\?v=\d+\.\d+\.\d+)?$/,
118
- type: 'asset/resource',
119
- generator: {
120
- filename: 'fonts/[name][ext]'
121
- }
114
+ return content;
115
+ },
116
+ },
122
117
  },
123
- {
124
- test: /\.mjs$/,
125
- include: /node_modules/,
126
- type: 'javascript/auto'
127
- }]
118
+ 'sass-loader',
119
+ ],
128
120
  },
129
- resolve: {
130
- extensions: [ '.ts', '.tsx', '.mjs', '.js', '.scss' ],
131
- alias: {
132
- ...(bundlePfModules ? {} : searchIgnoredStyles(rootFolder))
133
- },
134
- fallback: {
135
- path: require.resolve('path-browserify'),
136
- stream: require.resolve('stream-browserify'),
137
- zlib: require.resolve('browserify-zlib'),
138
- assert: require.resolve('assert/'),
139
- buffer: require.resolve('buffer/'),
140
- url: require.resolve('url/'),
141
- util: require.resolve('util/'),
142
- process: 'process/browser.js'
143
- }
121
+ {
122
+ test: /\.(woff(2)?|ttf|jpg|png|eot|gif|svg)(\?v=\d+\.\d+\.\d+)?$/,
123
+ type: 'asset/resource',
124
+ generator: {
125
+ filename: 'fonts/[name][ext]',
126
+ },
144
127
  },
145
- devServer: {
146
- static: {
147
- directory: `${rootFolder || ''}/dist`
148
- },
149
- port: devServerPort,
150
- https: https || Boolean(useProxy),
151
- host: '0.0.0.0', // This shares on local network. Needed for docker.host.internal
152
- hot: false, // Use livereload instead of HMR which is spotty with federated modules
153
- allowedHosts: 'all',
154
- // https://github.com/bripkens/connect-history-api-fallback
155
- historyApiFallback: {
156
- // We should really implement the same logic as cloud-services-config
157
- // and only redirect (/beta)?/bundle/app-name to /index.html
158
- //
159
- // Until then let known api calls fall through instead of returning /index.html
160
- // for easier `fetch` debugging
161
- rewrites: [
162
- { from: /^\/api/, to: '/404.html' },
163
- { from: /^(\/beta)?\/config/, to: '/404.html' }
164
- ],
165
- verbose: Boolean(proxyVerbose)
166
- },
167
- devMiddleware: {
168
- writeToDisk: true
169
- },
170
- client,
171
- ...proxy({
172
- useCloud,
173
- env,
174
- localChrome,
175
- keycloakUri,
176
- customProxy,
177
- routes,
178
- routesPath,
179
- useProxy,
180
- proxyURL,
181
- standalone,
182
- port: devServerPort,
183
- reposDir,
184
- appUrl,
185
- publicPath,
186
- proxyVerbose,
187
- target,
188
- registry,
189
- onBeforeSetupMiddleware: ({ chromePath }) => {
190
- if (useChromeTemplate && chromePath) {
191
- copyTemplate(chromePath);
192
- }
193
- }
194
- })
195
- }
196
- };
128
+ {
129
+ test: /\.mjs$/,
130
+ include: /node_modules/,
131
+ type: 'javascript/auto',
132
+ },
133
+ ],
134
+ },
135
+ resolve: {
136
+ extensions: ['.ts', '.tsx', '.mjs', '.js', '.scss'],
137
+ alias: {
138
+ ...(bundlePfModules ? {} : searchIgnoredStyles(rootFolder)),
139
+ },
140
+ fallback: {
141
+ path: require.resolve('path-browserify'),
142
+ stream: require.resolve('stream-browserify'),
143
+ zlib: require.resolve('browserify-zlib'),
144
+ assert: require.resolve('assert/'),
145
+ buffer: require.resolve('buffer/'),
146
+ url: require.resolve('url/'),
147
+ util: require.resolve('util/'),
148
+ process: 'process/browser.js',
149
+ },
150
+ },
151
+ devServer: {
152
+ static: {
153
+ directory: `${rootFolder || ''}/dist`,
154
+ },
155
+ port: devServerPort,
156
+ https: https || Boolean(useProxy),
157
+ host: '0.0.0.0', // This shares on local network. Needed for docker.host.internal
158
+ hot: false, // Use livereload instead of HMR which is spotty with federated modules
159
+ allowedHosts: 'all',
160
+ // https://github.com/bripkens/connect-history-api-fallback
161
+ historyApiFallback: {
162
+ // We should really implement the same logic as cloud-services-config
163
+ // and only redirect (/beta)?/bundle/app-name to /index.html
164
+ //
165
+ // Until then let known api calls fall through instead of returning /index.html
166
+ // for easier `fetch` debugging
167
+ rewrites: [
168
+ { from: /^\/api/, to: '/404.html' },
169
+ { from: /^(\/beta)?\/config/, to: '/404.html' },
170
+ ],
171
+ verbose: Boolean(proxyVerbose),
172
+ },
173
+ devMiddleware: {
174
+ writeToDisk: true,
175
+ },
176
+ client,
177
+ ...proxy({
178
+ useCloud,
179
+ env,
180
+ localChrome,
181
+ keycloakUri,
182
+ customProxy,
183
+ routes,
184
+ routesPath,
185
+ useProxy,
186
+ proxyURL,
187
+ standalone,
188
+ port: devServerPort,
189
+ reposDir,
190
+ appUrl,
191
+ publicPath,
192
+ proxyVerbose,
193
+ target,
194
+ registry,
195
+ onBeforeSetupMiddleware: ({ chromePath }) => {
196
+ if (useChromeTemplate && chromePath) {
197
+ copyTemplate(chromePath);
198
+ }
199
+ },
200
+ }),
201
+ },
202
+ };
197
203
  };