@redhat-cloud-services/frontend-components-config-utilities 1.5.9 → 1.5.12

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.
@@ -1,8 +1,8 @@
1
1
  /* eslint-disable max-len */
2
2
  function chromeRenderLoader(source) {
3
- const loaderUtils = require('loader-utils');
4
- const options = loaderUtils.getOptions(this);
5
- return `document.getElementById('root').classList.add('${options.appName}');var isChrome2 = (!${options.skipChrome2} && window.insights && window.insights.chrome && window.insights.chrome.isChrome2) || false; if(!isChrome2){${source}}`;
3
+ const loaderUtils = require('loader-utils');
4
+ const options = loaderUtils.getOptions(this);
5
+ return `document.getElementById('root').classList.add('${options.appName}');var isChrome2 = (!${options.skipChrome2} && window.insights && window.insights.chrome && window.insights.chrome.isChrome2) || false; if(!isChrome2){${source}}`;
6
6
  }
7
7
 
8
8
  module.exports = chromeRenderLoader;
@@ -1,44 +1,44 @@
1
1
  import chromeRenderLoader from './chrome-render-loader';
2
2
 
3
3
  jest.mock('loader-utils', () => ({
4
- getOptions: jest.fn().mockImplementation((that) => {
5
- return that.options;
6
- })
4
+ getOptions: jest.fn().mockImplementation((that) => {
5
+ return that.options;
6
+ }),
7
7
  }));
8
8
 
9
9
  describe('chromeRenderLoader', () => {
10
- beforeAll(() => {
11
- global.insights = {
12
- chrome: {
13
- isChrome2: true
14
- }
15
- };
16
- });
17
- test('add correct class', () => {
18
- const result = chromeRenderLoader.bind({
19
- options: {
20
- appName: 'someName'
21
- }
22
- })('something');
23
- expect(result.includes(`document.getElementById('root').classList.add('someName')`)).toBe(true);
24
- });
10
+ beforeAll(() => {
11
+ global.insights = {
12
+ chrome: {
13
+ isChrome2: true,
14
+ },
15
+ };
16
+ });
17
+ test('add correct class', () => {
18
+ const result = chromeRenderLoader.bind({
19
+ options: {
20
+ appName: 'someName',
21
+ },
22
+ })('something');
23
+ expect(result.includes(`document.getElementById('root').classList.add('someName')`)).toBe(true);
24
+ });
25
25
 
26
- test('calculate isChrome2 to be true', () => {
27
- const result = chromeRenderLoader.bind({
28
- options: {
29
- appName: 'someName'
30
- }
31
- })('something');
32
- expect(eval(result.match(/\((!.*(?=;))/)[0])).toBe(true);
33
- });
26
+ test('calculate isChrome2 to be true', () => {
27
+ const result = chromeRenderLoader.bind({
28
+ options: {
29
+ appName: 'someName',
30
+ },
31
+ })('something');
32
+ expect(eval(result.match(/\((!.*(?=;))/)[0])).toBe(true);
33
+ });
34
34
 
35
- test('calculate isChrome2 to be false', () => {
36
- const result = chromeRenderLoader.bind({
37
- options: {
38
- appName: 'someName',
39
- skipChrome2: true
40
- }
41
- })('something');
42
- expect(eval(result.match(/\((!.*(?=;))/)[0])).toBe(false);
43
- });
35
+ test('calculate isChrome2 to be false', () => {
36
+ const result = chromeRenderLoader.bind({
37
+ options: {
38
+ appName: 'someName',
39
+ skipChrome2: true,
40
+ },
41
+ })('something');
42
+ expect(eval(result.match(/\((!.*(?=;))/)[0])).toBe(false);
43
+ });
44
44
  });
package/chunk-mapper.js CHANGED
@@ -1,39 +1,42 @@
1
1
  class ChunkMapper {
2
- constructor(options) {
3
- this.config = {};
4
- this.options = options || {};
5
- }
2
+ constructor(options) {
3
+ this.config = {};
4
+ this.options = options || {};
5
+ }
6
6
 
7
- apply(compiler) {
8
- compiler.hooks.emit.tap('ChunkMapper', (compilation) => {
9
- const prefix = this.options.prefix || (RegExp('^/.*/$').test(compiler.options.output.publicPath) ? compiler.options.output.publicPath : '/');
10
- compilation.chunks.forEach(({ name, files, runtime }) => {
11
- const modules = Array.isArray(this.options.modules) ? this.options.modules : [ this.options.modules ];
12
- if (modules.find((oneEntry) => RegExp(`${oneEntry}$`).test(runtime))) {
13
- this.config[runtime] = {
14
- ...(this.config[runtime] || {}),
15
- ...(name === runtime
16
- ? {
17
- entry: Array.from(files).map(item => `${prefix}${item}`).filter((file, _index, array) => {
18
- if (array.find(item => !RegExp('\\.hot-update\\.js$').test(item))) {
19
- return !RegExp('\\.hot-update\\.js$').test(file);
20
- }
7
+ apply(compiler) {
8
+ compiler.hooks.emit.tap('ChunkMapper', (compilation) => {
9
+ const prefix = this.options.prefix || (RegExp('^/.*/$').test(compiler.options.output.publicPath) ? compiler.options.output.publicPath : '/');
10
+ compilation.chunks.forEach(({ name, files, runtime }) => {
11
+ const modules = Array.isArray(this.options.modules) ? this.options.modules : [this.options.modules];
12
+ if (modules.find((oneEntry) => RegExp(`${oneEntry}$`).test(runtime))) {
13
+ this.config[runtime] = {
14
+ ...(this.config[runtime] || {}),
15
+ ...(name === runtime
16
+ ? {
17
+ entry: Array.from(files)
18
+ .map((item) => `${prefix}${item}`)
19
+ .filter((file, _index, array) => {
20
+ if (array.find((item) => !RegExp('\\.hot-update\\.js$').test(item))) {
21
+ return !RegExp('\\.hot-update\\.js$').test(file);
22
+ }
21
23
 
22
- return true;
23
- })
24
- } : {
25
- modules: [ ...(this.config[runtime].modules || []), ...Array.from(files).map((item) => `${prefix}${item}`) ]
26
- })
27
- };
24
+ return true;
25
+ }),
28
26
  }
29
- });
27
+ : {
28
+ modules: [...(this.config[runtime].modules || []), ...Array.from(files).map((item) => `${prefix}${item}`)],
29
+ }),
30
+ };
31
+ }
32
+ });
30
33
 
31
- compilation.assets['fed-mods.json'] = {
32
- source: () => JSON.stringify(this.config, null, 4),
33
- size: () => JSON.stringify(this.config, null, 4).length
34
- };
35
- });
36
- }
34
+ compilation.assets['fed-mods.json'] = {
35
+ source: () => JSON.stringify(this.config, null, 4),
36
+ size: () => JSON.stringify(this.config, null, 4).length,
37
+ };
38
+ });
39
+ }
37
40
  }
38
41
 
39
42
  module.exports = ChunkMapper;
@@ -3,51 +3,51 @@
3
3
  const jws = require('jws');
4
4
 
5
5
  const defaultEntitlements = {
6
- insights: { is_entitled: true },
7
- smart_management: { is_entitled: true },
8
- openshift: { is_entitled: true },
9
- hybrid: { is_entitled: true },
10
- migrations: { is_entitled: true },
11
- ansible: { is_entitled: true },
12
- cost_management: { is_entitled: true }
6
+ insights: { is_entitled: true },
7
+ smart_management: { is_entitled: true },
8
+ openshift: { is_entitled: true },
9
+ hybrid: { is_entitled: true },
10
+ migrations: { is_entitled: true },
11
+ ansible: { is_entitled: true },
12
+ cost_management: { is_entitled: true },
13
13
  };
14
14
 
15
15
  function cookieTransform(proxyReq, req, _res, { entitlements = defaultEntitlements, user, internal, identity: customIdentity }) {
16
- const cookie = req.headers.cookie;
17
- const match = cookie && cookie.match(/cs_jwt=([^;]+)/);
18
- if (match) {
19
- const cs_jwt = match[1];
20
- const { payload } = jws.decode(cs_jwt);
16
+ const cookie = req.headers.cookie;
17
+ const match = cookie && cookie.match(/cs_jwt=([^;]+)/);
18
+ if (match) {
19
+ const cs_jwt = match[1];
20
+ const { payload } = jws.decode(cs_jwt);
21
21
 
22
- const identity = {
23
- entitlements,
24
- identity: {
25
- type: 'User',
26
- auth_type: 'basic-auth',
27
- account_number: payload.account_number + '',
28
- ...customIdentity,
29
- user: {
30
- username: payload.username,
31
- email: payload.email,
32
- first_name: payload.first_name,
33
- last_name: payload.last_name,
34
- is_active: true,
35
- is_org_admin: payload.is_org_admin,
36
- is_internal: payload.is_internal,
37
- locale: 'en-US',
38
- user_id: payload.account_id + '',
39
- ...user
40
- },
41
- internal: {
42
- org_id: payload.org_id,
43
- auth_time: payload.auth_time,
44
- ...internal
45
- }
46
- }
47
- };
48
- const identityB64 = Buffer.from(JSON.stringify(identity), 'utf8').toString('base64');
49
- proxyReq.setHeader('x-rh-identity', identityB64);
50
- }
22
+ const identity = {
23
+ entitlements,
24
+ identity: {
25
+ type: 'User',
26
+ auth_type: 'basic-auth',
27
+ account_number: payload.account_number + '',
28
+ ...customIdentity,
29
+ user: {
30
+ username: payload.username,
31
+ email: payload.email,
32
+ first_name: payload.first_name,
33
+ last_name: payload.last_name,
34
+ is_active: true,
35
+ is_org_admin: payload.is_org_admin,
36
+ is_internal: payload.is_internal,
37
+ locale: 'en-US',
38
+ user_id: payload.account_id + '',
39
+ ...user,
40
+ },
41
+ internal: {
42
+ org_id: payload.org_id,
43
+ auth_time: payload.auth_time,
44
+ ...internal,
45
+ },
46
+ },
47
+ };
48
+ const identityB64 = Buffer.from(JSON.stringify(identity), 'utf8').toString('base64');
49
+ proxyReq.setHeader('x-rh-identity', identityB64);
50
+ }
51
51
  }
52
52
 
53
53
  module.exports = cookieTransform;
@@ -1,77 +1,77 @@
1
1
  const webpack = require('webpack');
2
2
 
3
3
  class ExtensionsMapper {
4
- constructor(plugin, options) {
5
- if (!plugin) {
6
- throw new Error('Missing plugin config!');
7
- }
8
-
9
- this.plugin = plugin;
10
- this.options = {
11
- remoteEntryCallback: 'window.loadPluginEntry',
12
- remoteEntryFile: 'plugin-entry.js',
13
- pluginManifestFile: 'plugin-manifest.json',
14
- ...options
15
- };
4
+ constructor(plugin, options) {
5
+ if (!plugin) {
6
+ throw new Error('Missing plugin config!');
16
7
  }
17
8
 
18
- apply(compiler) {
19
- compiler.hooks.thisCompilation.tap(ExtensionsMapper.name, (compilation) => {
20
- // Generate extensions manifest
21
- compilation.hooks.processAssets.tap(
22
- {
23
- name: ExtensionsMapper.name,
24
- stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL
25
- },
26
- () => {
27
- compilation.emitAsset(
28
- this.options.pluginManifestFile,
29
- new webpack.sources.RawSource(
30
- Buffer.from(JSON.stringify({
31
- version: '0.0.0',
32
- description: '',
33
- displayName: '',
34
- dependencies: {},
35
- disableStaticPlugins: {},
36
- ...this.plugin
37
- }, null, 2))
38
- )
39
- );
40
- }
41
- );
9
+ this.plugin = plugin;
10
+ this.options = {
11
+ remoteEntryCallback: 'window.loadPluginEntry',
12
+ remoteEntryFile: 'plugin-entry.js',
13
+ pluginManifestFile: 'plugin-manifest.json',
14
+ ...options,
15
+ };
16
+ }
17
+
18
+ apply(compiler) {
19
+ compiler.hooks.thisCompilation.tap(ExtensionsMapper.name, (compilation) => {
20
+ // Generate extensions manifest
21
+ compilation.hooks.processAssets.tap(
22
+ {
23
+ name: ExtensionsMapper.name,
24
+ stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,
25
+ },
26
+ () => {
27
+ compilation.emitAsset(
28
+ this.options.pluginManifestFile,
29
+ new webpack.sources.RawSource(
30
+ Buffer.from(
31
+ JSON.stringify(
32
+ {
33
+ version: '0.0.0',
34
+ description: '',
35
+ displayName: '',
36
+ dependencies: {},
37
+ disableStaticPlugins: {},
38
+ ...this.plugin,
39
+ },
40
+ null,
41
+ 2
42
+ )
43
+ )
44
+ )
45
+ );
46
+ }
47
+ );
42
48
 
43
- // Update plugin-entry.js file
44
- compilation.hooks.processAssets.tap(
45
- {
46
- name: ExtensionsMapper.name,
47
- stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS
48
- },
49
- () => {
50
- compilation.updateAsset(this.options.remoteEntryFile, (source) => {
51
- const newSource = new webpack.sources.ReplaceSource(source);
49
+ // Update plugin-entry.js file
50
+ compilation.hooks.processAssets.tap(
51
+ {
52
+ name: ExtensionsMapper.name,
53
+ stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
54
+ },
55
+ () => {
56
+ compilation.updateAsset(this.options.remoteEntryFile, (source) => {
57
+ const newSource = new webpack.sources.ReplaceSource(source);
52
58
 
53
- const fromIndex = source
54
- .source()
55
- .toString()
56
- .indexOf(`${this.options.remoteEntryCallback}(`);
59
+ const fromIndex = source.source().toString().indexOf(`${this.options.remoteEntryCallback}(`);
57
60
 
58
- if (fromIndex < 0) {
59
- const error = new webpack.WebpackError(`Missing call to ${this.options.remoteEntryCallback}`);
60
- error.file = this.options.remoteEntryFile;
61
- compilation.errors.push(error);
62
- } else {
63
- newSource.insert(
64
- fromIndex + this.options.remoteEntryCallback.length + 1,
65
- `'${this.plugin.name}@${this.plugin.version}', `
66
- );
67
- }
61
+ if (fromIndex < 0) {
62
+ const error = new webpack.WebpackError(`Missing call to ${this.options.remoteEntryCallback}`);
63
+ error.file = this.options.remoteEntryFile;
64
+ compilation.errors.push(error);
65
+ } else {
66
+ newSource.insert(fromIndex + this.options.remoteEntryCallback.length + 1, `'${this.plugin.name}@${this.plugin.version}', `);
67
+ }
68
68
 
69
- return newSource;
70
- });
71
- }
72
- );
73
- });
74
- }
69
+ return newSource;
70
+ });
71
+ }
72
+ );
73
+ });
74
+ }
75
75
  }
76
76
 
77
77
  module.exports = ExtensionsMapper;
@@ -3,52 +3,52 @@ const fedModule = require('./federated-modules');
3
3
  const ExtensionsMapper = require('./extension-mapper');
4
4
 
5
5
  class ExtensionsPlugin {
6
- constructor(plugin, fedMod, options) {
7
- if (!plugin) {
8
- throw new Error('Missing plugin config!');
9
- }
10
-
11
- this.plugin = plugin;
12
- this.fedMod = {
13
- moduleName: 'plugin-entry',
14
- libName: 'window.loadPluginEntry',
15
- useFileHash: false,
16
- libType: 'jsonp',
17
- ...fedMod
18
- };
19
- this.options = {
20
- remoteEntryCallback: 'window.loadPluginEntry',
21
- remoteEntryFile: `${this.fedMod.moduleName}.js`,
22
- pluginManifestFile: 'plugin-manifest.json',
23
- ...options
24
- };
6
+ constructor(plugin, fedMod, options) {
7
+ if (!plugin) {
8
+ throw new Error('Missing plugin config!');
25
9
  }
26
10
 
27
- apply(compiler) {
28
- const root = this.fedMod.root || compiler.context;
29
- const { insights, version, description } = require(resolve(root, './package.json')) || {};
11
+ this.plugin = plugin;
12
+ this.fedMod = {
13
+ moduleName: 'plugin-entry',
14
+ libName: 'window.loadPluginEntry',
15
+ useFileHash: false,
16
+ libType: 'jsonp',
17
+ ...fedMod,
18
+ };
19
+ this.options = {
20
+ remoteEntryCallback: 'window.loadPluginEntry',
21
+ remoteEntryFile: `${this.fedMod.moduleName}.js`,
22
+ pluginManifestFile: 'plugin-manifest.json',
23
+ ...options,
24
+ };
25
+ }
30
26
 
31
- // create federation module
32
- fedModule({
33
- ...this.fedMod,
34
- root
35
- }).apply(compiler);
27
+ apply(compiler) {
28
+ const root = this.fedMod.root || compiler.context;
29
+ const { insights, version, description } = require(resolve(root, './package.json')) || {};
36
30
 
37
- // generate plugin manifest and update plugin-entry file
38
- new ExtensionsMapper(
39
- {
40
- ...this.plugin,
41
- name: this.plugin.name || (insights && insights.appname),
42
- version: this.plugin.version || version || '0.0.0',
43
- displayName: this.plugin.displayName || '',
44
- description: this.plugin.description || description || '',
45
- dependencies: { ...this.plugin.dependencies || {} },
46
- disableStaticPlugins: [ ...this.plugin.disableStaticPlugins || [] ],
47
- extensions: [ ...this.plugin.extensions || [] ]
48
- },
49
- this.options
50
- ).apply(compiler);
51
- }
31
+ // create federation module
32
+ fedModule({
33
+ ...this.fedMod,
34
+ root,
35
+ }).apply(compiler);
36
+
37
+ // generate plugin manifest and update plugin-entry file
38
+ new ExtensionsMapper(
39
+ {
40
+ ...this.plugin,
41
+ name: this.plugin.name || (insights && insights.appname),
42
+ version: this.plugin.version || version || '0.0.0',
43
+ displayName: this.plugin.displayName || '',
44
+ description: this.plugin.description || description || '',
45
+ dependencies: { ...(this.plugin.dependencies || {}) },
46
+ disableStaticPlugins: [...(this.plugin.disableStaticPlugins || [])],
47
+ extensions: [...(this.plugin.extensions || [])],
48
+ },
49
+ this.options
50
+ ).apply(compiler);
51
+ }
52
52
  }
53
53
 
54
54
  module.exports = ExtensionsPlugin;
@@ -4,77 +4,71 @@ const { ModuleFederationPlugin } = require('webpack').container;
4
4
  const jsVarName = require('./jsVarName');
5
5
 
6
6
  const include = {
7
- '@patternfly/react-core': {},
8
- '@patternfly/react-table': {},
9
- '@patternfly/react-tokens': {},
10
- '@patternfly/react-icons': {},
11
- '@patternfly/quickstarts': { singleton: true },
12
- '@redhat-cloud-services/frontend-components': {},
13
- '@redhat-cloud-services/frontend-components-utilities': {},
14
- '@redhat-cloud-services/frontend-components-notifications': {},
15
- axios: {},
16
- lodash: {},
17
- 'redux-promise-middleware': {},
18
- react: { singleton: true },
19
- 'react-dom': { singleton: true },
20
- 'react-router-dom': {}
7
+ '@patternfly/react-core': { eager: true },
8
+ '@patternfly/react-table': { eager: true },
9
+ '@patternfly/react-tokens': {},
10
+ '@patternfly/react-icons': {},
11
+ '@patternfly/quickstarts': { singleton: true, eager: true },
12
+ '@redhat-cloud-services/frontend-components': {},
13
+ '@redhat-cloud-services/frontend-components-utilities': {},
14
+ '@redhat-cloud-services/frontend-components-notifications': {},
15
+ axios: {},
16
+ lodash: {},
17
+ 'redux-promise-middleware': {},
18
+ react: { singleton: true, eager: true },
19
+ 'react-dom': { singleton: true, eager: true },
20
+ 'react-router-dom': { eager: true },
21
21
  };
22
22
 
23
- module.exports = ({
24
- root,
25
- exposes,
26
- shared = [],
27
- debug,
28
- moduleName,
29
- useFileHash = true,
30
- libType = 'var',
31
- libName,
32
- exclude = []
33
- }) => {
34
- const { dependencies, insights } = require(resolve(root, './package.json')) || {};
35
- const appName = moduleName || (insights && jsVarName(insights.appname));
23
+ module.exports = ({ root, exposes, shared = [], debug, moduleName, useFileHash = true, libType = 'var', libName, exclude = [] }) => {
24
+ const { dependencies, insights } = require(resolve(root, './package.json')) || {};
25
+ const appName = moduleName || (insights && jsVarName(insights.appname));
36
26
 
37
- const sharedDeps = Object.entries(include)
38
- .filter(([ key ]) => dependencies[key] && !exclude.includes(key))
39
- .map(([ key, val ]) => ({
40
- [key]: {
41
- requiredVersion: dependencies[key],
42
- ...val
43
- }
27
+ const sharedDeps = Object.entries(include)
28
+ .filter(([key]) => dependencies[key] && !exclude.includes(key))
29
+ .map(([key, val]) => ({
30
+ [key]: {
31
+ requiredVersion: dependencies[key],
32
+ ...val,
33
+ },
44
34
  }));
45
35
 
46
- /**
47
- * Add scalprum and force it as singletong.
48
- * It is required to share the context via `useChrome`.
49
- * No application should be installing/interacting with scalprum directly.
50
- */
51
- if (dependencies['@redhat-cloud-services/frontend-components']) {
52
- sharedDeps.push({ '@scalprum/react-core': { requiredVersion: '*', singleton: true } });
53
- }
36
+ /**
37
+ * Add scalprum and force it as singletong.
38
+ * It is required to share the context via `useChrome`.
39
+ * No application should be installing/interacting with scalprum directly.
40
+ */
41
+ if (dependencies['@redhat-cloud-services/frontend-components']) {
42
+ sharedDeps.push({ '@scalprum/react-core': { requiredVersion: '*', singleton: true } });
43
+ }
44
+
45
+ /**
46
+ * Make sure the unleash proxy client is a singleton
47
+ */
48
+ if (dependencies['@unleash/proxy-client-react']) {
49
+ sharedDeps.push({ '@unleash/proxy-client-react': { singleton: true, requiredVersion: dependencies['@unleash/proxy-client-react'] } });
50
+ }
54
51
 
55
- if (debug) {
56
- console.log('Using package at path: ', resolve(root, './package.json'));
57
- console.log('Using appName: ', appName);
58
- console.log(`Using ${exposes ? 'custom' : 'default'} exposes`);
59
- console.log('Number of custom shared modules is: ', shared.length);
60
- console.log('Number of default shared modules is: ', sharedDeps.length);
61
- if (exclude.length > 0) {
62
- console.log('Excluding default packages', exclude);
63
- }
52
+ if (debug) {
53
+ console.log('Using package at path: ', resolve(root, './package.json'));
54
+ console.log('Using appName: ', appName);
55
+ console.log(`Using ${exposes ? 'custom' : 'default'} exposes`);
56
+ console.log('Number of custom shared modules is: ', shared.length);
57
+ console.log('Number of default shared modules is: ', sharedDeps.length);
58
+ if (exclude.length > 0) {
59
+ console.log('Excluding default packages', exclude);
64
60
  }
61
+ }
65
62
 
66
- return new ModuleFederationPlugin({
67
- name: appName,
68
- filename: `${appName}${useFileHash ? `.${Date.now()}.[fullhash]` : ''}.js`,
69
- library: { type: libType, name: libName || appName },
70
- exposes: {
71
- ...exposes || {
72
- './RootApp': resolve(root, './src/AppEntry')
73
- }
74
- },
75
- shared: [
76
- ...sharedDeps,
77
- ...shared
78
- ]
79
- });
63
+ return new ModuleFederationPlugin({
64
+ name: appName,
65
+ filename: `${appName}${useFileHash ? `.${Date.now()}.[fullhash]` : ''}.js`,
66
+ library: { type: libType, name: libName || appName },
67
+ exposes: {
68
+ ...(exposes || {
69
+ './RootApp': resolve(root, './src/AppEntry'),
70
+ }),
71
+ },
72
+ shared: [...sharedDeps, ...shared],
73
+ });
80
74
  };
package/jsVarName.js CHANGED
@@ -1,11 +1,13 @@
1
1
  function jsVarName(s) {
2
- return s
3
- // Camel case dashes
4
- .replace(/-(\w)/g, (_, match) => match.toUpperCase())
5
- // Remove leading digits
6
- .replace(/^[0-9]+/, '')
7
- // Remove all non alphanumeric chars
8
- .replace(/[^A-Za-z0-9]+/g, '');
2
+ return (
3
+ s
4
+ // Camel case dashes
5
+ .replace(/-(\w)/g, (_, match) => match.toUpperCase())
6
+ // Remove leading digits
7
+ .replace(/^[0-9]+/, '')
8
+ // Remove all non alphanumeric chars
9
+ .replace(/[^A-Za-z0-9]+/g, '')
10
+ );
9
11
  }
10
12
 
11
13
  module.exports = jsVarName;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redhat-cloud-services/frontend-components-config-utilities",
3
- "version": "1.5.9",
3
+ "version": "1.5.12",
4
4
  "description": "Utilities for shared config used in RedHat Cloud Services project.",
5
5
  "main": "index.js",
6
6
  "publishConfig": {
package/proxy.js CHANGED
@@ -15,264 +15,270 @@ const { registerChrome } = require('./standalone/services/default/chrome');
15
15
  const defaultReposDir = path.join(__dirname, 'repos');
16
16
 
17
17
  module.exports = ({
18
- env = 'ci-beta',
19
- customProxy = [],
20
- routes,
21
- routesPath,
22
- useProxy,
23
- proxyURL = 'http://squid.corp.redhat.com:3128',
24
- standalone,
25
- port,
26
- reposDir = defaultReposDir,
27
- localChrome,
28
- appUrl = [],
29
- publicPath,
30
- proxyVerbose,
31
- useCloud = false,
32
- target = '',
33
- keycloakUri = '',
34
- registry = [],
35
- isChrome = false,
36
- onBeforeSetupMiddleware = () => {}
18
+ env = 'ci-beta',
19
+ customProxy = [],
20
+ routes,
21
+ routesPath,
22
+ useProxy,
23
+ proxyURL = 'http://squid.corp.redhat.com:3128',
24
+ standalone,
25
+ port,
26
+ reposDir = defaultReposDir,
27
+ localChrome,
28
+ appUrl = [],
29
+ publicPath,
30
+ proxyVerbose,
31
+ useCloud = false,
32
+ target = '',
33
+ keycloakUri = '',
34
+ registry = [],
35
+ isChrome = false,
36
+ onBeforeSetupMiddleware = () => {},
37
37
  }) => {
38
- const proxy = [];
39
- const majorEnv = env.split('-')[0];
40
- if (target === '') {
41
- target += 'https://';
42
- if (![ 'prod', 'stage' ].includes(majorEnv)) {
43
- target += majorEnv + '.';
44
- }
45
-
46
- target += useCloud ? 'cloud' : 'console';
47
- if (majorEnv === 'stage') {
48
- target += '.stage';
49
- }
50
-
51
- target += '.redhat.com/';
38
+ const proxy = [];
39
+ const majorEnv = env.split('-')[0];
40
+ if (target === '') {
41
+ target += 'https://';
42
+ if (!['prod', 'stage'].includes(majorEnv)) {
43
+ target += majorEnv + '.';
52
44
  }
53
45
 
54
- let agent;
55
-
56
- if (env.startsWith('prod') || env.startsWith('stage')) {
57
- // PROD and stage are deployed with Akamai which requires a corporate proxy
58
- agent = new HttpsProxyAgent(proxyURL);
46
+ target += useCloud ? 'cloud' : 'console';
47
+ if (majorEnv === 'stage') {
48
+ target += '.stage';
59
49
  }
60
50
 
61
- if (env.startsWith('stage')) {
62
- // stage-stable / stage-beta branches don't exist in build repos
63
- // Currently stage pulls from QA
64
- env = env.replace('stage', 'qa');
65
- }
66
-
67
- if (!Array.isArray(appUrl)) {
68
- appUrl = [ appUrl ];
69
- }
51
+ target += '.redhat.com/';
52
+ }
53
+
54
+ let agent;
55
+
56
+ if (env.startsWith('prod') || env.startsWith('stage')) {
57
+ // PROD and stage are deployed with Akamai which requires a corporate proxy
58
+ agent = new HttpsProxyAgent(proxyURL);
59
+ }
60
+
61
+ if (env.startsWith('stage')) {
62
+ // stage-stable / stage-beta branches don't exist in build repos
63
+ // Currently stage pulls from QA
64
+ env = env.replace('stage', 'qa');
65
+ }
66
+
67
+ if (!Array.isArray(appUrl)) {
68
+ appUrl = [appUrl];
69
+ }
70
+
71
+ appUrl.push(publicPath);
72
+
73
+ if (routesPath) {
74
+ routes = require(routesPath);
75
+ }
76
+
77
+ if (routes) {
78
+ routes = routes.routes || routes;
79
+ console.log('Making proxy from SPANDX routes');
80
+ proxy.push(
81
+ ...Object.entries(routes || {}).map(([route, redirect]) => {
82
+ const currTarget = redirect.host || redirect;
83
+ delete redirect.host;
84
+ return {
85
+ context: (path) => path.includes(route),
86
+ target: currTarget === 'PORTAL_BACKEND_MARKER' ? target : currTarget,
87
+ secure: false,
88
+ changeOrigin: true,
89
+ autoRewrite: true,
90
+ ws: true,
91
+ onProxyReq: cookieTransform,
92
+ ...(currTarget === 'PORTAL_BACKEND_MARKER' && { router }),
93
+ ...(typeof redirect === 'object' ? redirect : {}),
94
+ };
95
+ })
96
+ );
97
+ }
98
+
99
+ if (customProxy) {
100
+ proxy.push(...customProxy);
101
+ }
102
+
103
+ let standaloneConfig;
104
+ if (standalone) {
105
+ standaloneConfig = getConfig(standalone, localChrome, env, port);
106
+ // Create network for services.
107
+ execSync(`docker network inspect ${NET} >/dev/null 2>&1 || docker network create ${NET}`);
108
+
109
+ // Clone repos and resolve functions
110
+ // If we manage the repos it's okay to overwrite the contents
111
+ const overwrite = reposDir === defaultReposDir;
112
+
113
+ // Resolve config functions for cross-service references
114
+ for (const [, proj] of Object.entries(standaloneConfig)) {
115
+ const { services, path, assets, register } = proj;
116
+ if (typeof register === 'function') {
117
+ registry.push(register);
118
+ }
119
+
120
+ if (isGitUrl(path)) {
121
+ // Add typical branch if not included
122
+ if (!path.includes('#')) {
123
+ proj.path = `${path}#${env}`;
124
+ }
70
125
 
71
- appUrl.push(publicPath);
126
+ proj.path = checkoutRepo({ repo: proj.path, reposDir, overwrite });
127
+ }
72
128
 
73
- if (routesPath) {
74
- routes = require(routesPath);
75
- }
129
+ Object.keys(assets || []).forEach((key) => {
130
+ if (isGitUrl(assets[key])) {
131
+ assets[key] = checkoutRepo({ repo: assets[key], reposDir, overwrite });
132
+ }
133
+ });
76
134
 
77
- if (routes) {
78
- routes = routes.routes || routes;
79
- console.log('Making proxy from SPANDX routes');
80
- proxy.push(
81
- ...Object.entries(routes || {}).map(([ route, redirect ]) => {
82
- const currTarget = redirect.host || redirect;
83
- delete redirect.host;
84
- return {
85
- context: (path) => path.includes(route),
86
- target: currTarget === 'PORTAL_BACKEND_MARKER' ? target : currTarget,
87
- secure: false,
88
- changeOrigin: true,
89
- autoRewrite: true,
90
- ws: true,
91
- onProxyReq: cookieTransform,
92
- ...(currTarget === 'PORTAL_BACKEND_MARKER' && { router }),
93
- ...typeof redirect === 'object' ? redirect : {}
94
- };
95
- })
96
- );
135
+ // Resolve functions that depend on env, port, or assets
136
+ if (typeof services === 'function') {
137
+ proj.services = services({ env, port, assets });
138
+ }
97
139
  }
98
140
 
99
- if (customProxy) {
100
- proxy.push(...customProxy);
141
+ // Start standalone services.
142
+ for (const [projName, proj] of Object.entries(standaloneConfig)) {
143
+ const { services, path, assets, onProxyReq, keycloakUri, register, target, ...rest } = proj;
144
+ const serviceNames = [];
145
+ for (let [subServiceName, subService] of Object.entries(proj.services || {})) {
146
+ const name = [projName, subServiceName].join('_');
147
+ startService(standaloneConfig, name, subService);
148
+ serviceNames.push(name);
149
+ const port = getExposedPort(subService.args);
150
+ console.log('Container', name, 'listening', port ? 'on' : '', port || '');
151
+ }
152
+
153
+ process.on('SIGINT', () => serviceNames.forEach(stopService));
154
+
155
+ if (target) {
156
+ proxy.push({
157
+ secure: false,
158
+ changeOrigin: true,
159
+ onProxyReq: cookieTransform,
160
+ target,
161
+ ...rest,
162
+ });
163
+ }
101
164
  }
102
165
 
103
- let standaloneConfig;
104
- if (standalone) {
105
- standaloneConfig = getConfig(standalone, localChrome, env, port);
106
- // Create network for services.
107
- execSync(`docker network inspect ${NET} >/dev/null 2>&1 || docker network create ${NET}`);
108
-
109
- // Clone repos and resolve functions
110
- // If we manage the repos it's okay to overwrite the contents
111
- const overwrite = reposDir === defaultReposDir;
112
-
113
- // Resolve config functions for cross-service references
114
- for (const [ _projName, proj ] of Object.entries(standaloneConfig)) {
115
- const { services, path, assets, register } = proj;
116
- if (typeof register === 'function') {
117
- registry.push(register);
118
- }
119
-
120
- if (isGitUrl(path)) {
121
- // Add typical branch if not included
122
- if (!path.includes('#')) {
123
- proj.path = `${path}#${env}`;
124
- }
125
-
126
- proj.path = checkoutRepo({ repo: proj.path, reposDir, overwrite });
127
- }
128
-
129
- Object.keys(assets || []).forEach(key => {
130
- if (isGitUrl(assets[key])) {
131
- assets[key] = checkoutRepo({ repo: assets[key], reposDir, overwrite });
132
- }
133
- });
134
-
135
- // Resolve functions that depend on env, port, or assets
136
- if (typeof services === 'function') {
137
- proj.services = services({ env, port, assets });
138
- }
166
+ process.on('SIGINT', () => process.exit());
167
+ }
168
+
169
+ if (useProxy) {
170
+ // Catch-all
171
+ proxy.push({
172
+ secure: false,
173
+ changeOrigin: true,
174
+ autoRewrite: true,
175
+ context: (url) => {
176
+ const shouldProxy = !appUrl.find((u) => (typeof u === 'string' ? url.startsWith(u) : u.test(url)));
177
+ if (shouldProxy) {
178
+ if (proxyVerbose) {
179
+ console.log('proxy', url);
180
+ }
181
+
182
+ return true;
139
183
  }
140
184
 
141
- // Start standalone services.
142
- for (const [ projName, proj ] of Object.entries(standaloneConfig)) {
143
- const { services, path, assets, onProxyReq, keycloakUri, register, target, ...rest } = proj;
144
- const serviceNames = [];
145
- for (let [ subServiceName, subService ] of Object.entries(proj.services || {})) {
146
- const name = [ projName, subServiceName ].join('_');
147
- startService(standaloneConfig, name, subService);
148
- serviceNames.push(name);
149
- const port = getExposedPort(subService.args);
150
- console.log('Container', name, 'listening', port ? 'on' : '', port || '');
151
- }
152
-
153
- process.on('SIGINT', () => serviceNames.forEach(stopService));
154
-
155
- if (target) {
156
- proxy.push({
157
- secure: false,
158
- changeOrigin: true,
159
- onProxyReq: cookieTransform,
160
- target,
161
- ...rest
162
- });
163
- }
185
+ return false;
186
+ },
187
+ target,
188
+ ...(isChrome && {
189
+ bypass: (req) => {
190
+ /**
191
+ * Bypass any HTML requests if using chrome
192
+ * Serves as a historyApiFallback when refreshing on any other URL than '/'
193
+ */
194
+ if (!req.url.match(/\/api\//) && !req.url.match(/\./) && req.headers.accept.includes('text/html')) {
195
+ return '/';
196
+ }
197
+
198
+ return null;
199
+ },
200
+ }),
201
+ router: router(target, useCloud),
202
+ ...(agent && {
203
+ agent,
204
+ headers: {
205
+ // Staging Akamai CORS gives 403s for non-GET requests from non-origin hosts
206
+ Host: target.replace('https://', ''),
207
+ Origin: target,
208
+ },
209
+ }),
210
+ });
211
+ }
212
+
213
+ return {
214
+ ...(proxy.length > 0 && { proxy }),
215
+ onListening(server) {
216
+ if (useProxy || standaloneConfig) {
217
+ const host = useProxy ? `${majorEnv}.foo.redhat.com` : 'localhost';
218
+ const origin = `http${server.options.https ? 's' : ''}://${host}:${server.options.port}`;
219
+ console.log('App should run on:');
220
+
221
+ console.log('\u001b[34m'); // Use same webpack-dev-server blue
222
+ if (appUrl.length > 0) {
223
+ appUrl.slice(0, appUrl.length - 1).forEach((url) => console.log(` - ${origin}${url}`));
224
+
225
+ console.log('\x1b[0m');
226
+ console.log('Static assets are available at:');
227
+ console.log('\u001b[34m'); // Use same webpack-dev-server blue
228
+ console.log(` - ${origin}${appUrl[appUrl.length - 1]}`);
229
+ } else {
230
+ console.log(` - ${origin}`);
164
231
  }
165
232
 
166
- process.on('SIGINT', () => process.exit());
167
- }
233
+ console.log('\u001b[0m');
234
+ }
235
+ },
236
+ onBeforeSetupMiddleware({ app, compiler, options }) {
237
+ app.enable('strict routing'); // trailing slashes are mean
238
+ /**
239
+ * Allow serving chrome assets
240
+ * This will allow running chrome as a host application
241
+ */
242
+ if (!isChrome) {
243
+ let chromePath = localChrome;
244
+ if (standaloneConfig) {
245
+ if (standaloneConfig.chrome) {
246
+ chromePath = resolvePath(reposDir, standaloneConfig.chrome.path);
247
+ keycloakUri = standaloneConfig.chrome.keycloakUri;
248
+ }
249
+ } else if (!localChrome && useProxy) {
250
+ if (typeof defaultServices.chrome === 'function') {
251
+ defaultServices.chrome = defaultServices.chrome({});
252
+ }
253
+
254
+ chromePath = checkoutRepo({
255
+ repo: `${defaultServices.chrome.path}#${env}`,
256
+ reposDir,
257
+ overwrite: true,
258
+ });
259
+ }
168
260
 
169
- if (useProxy) {
170
- // Catch-all
171
- proxy.push({
172
- secure: false,
173
- changeOrigin: true,
174
- autoRewrite: true,
175
- context: url => {
176
- const shouldProxy = !appUrl.find(u => typeof u === 'string' ? url.startsWith(u) : u.test(url));
177
- if (shouldProxy) {
178
- if (proxyVerbose) {
179
- console.log('proxy', url);
180
- }
181
-
182
- return true;
183
- }
184
-
185
- return false;
186
- },
187
- target,
188
- ...(isChrome && {
189
- bypass: (req) => {
190
- /**
191
- * Bypass any HTML requests if using chrome
192
- * Serves as a historyApiFallback when refreshing on any other URL than '/'
193
- */
194
- if (!req.url.match(/\/api\//) && !req.url.match(/\./) && req.headers.accept.includes('text/html')) {
195
- return '/';
196
- }
197
-
198
- return null;
199
- }
200
- }),
201
- router: router(target, useCloud),
202
- ...(agent && {
203
- agent,
204
- headers: {
205
- // Staging Akamai CORS gives 403s for non-GET requests from non-origin hosts
206
- Host: target.replace('https://', ''),
207
- Origin: target
208
- }
209
- })
210
- });
211
- }
261
+ onBeforeSetupMiddleware({ chromePath });
212
262
 
213
- return {
214
- ...(proxy.length > 0 && { proxy }),
215
- onListening(server) {
216
- if (useProxy || standaloneConfig) {
217
- const host = useProxy ? `${majorEnv}.foo.redhat.com` : 'localhost';
218
- const origin = `http${server.options.https ? 's' : ''}://${host}:${server.options.port}`;
219
- console.log('App should run on:');
220
-
221
- console.log('\u001b[34m'); // Use same webpack-dev-server blue
222
- if (appUrl.length > 0) {
223
- appUrl.forEach(url => console.log(` - ${origin}${url}`));
224
- } else {
225
- console.log(` - ${origin}`);
226
- }
227
-
228
- console.log('\u001b[0m');
229
- }
230
- },
231
- onBeforeSetupMiddleware({ app, compiler, options }) {
232
- app.enable('strict routing'); // trailing slashes are mean
233
- /**
234
- * Allow serving chrome assets
235
- * This will allow running chrome as a host application
236
- */
237
- if (!isChrome) {
238
- let chromePath = localChrome;
239
- if (standaloneConfig) {
240
- if (standaloneConfig.chrome) {
241
- chromePath = resolvePath(reposDir, standaloneConfig.chrome.path);
242
- keycloakUri = standaloneConfig.chrome.keycloakUri;
243
- }
244
- } else if (!localChrome && useProxy) {
245
- if (typeof defaultServices.chrome === 'function') {
246
- defaultServices.chrome = defaultServices.chrome({});
247
- }
248
-
249
- chromePath = checkoutRepo({
250
- repo: `${defaultServices.chrome.path}#${env}`,
251
- reposDir,
252
- overwrite: true
253
- });
254
- }
255
-
256
- onBeforeSetupMiddleware({ chromePath });
257
-
258
- if (chromePath) {
259
- registerChrome({
260
- app,
261
- chromePath,
262
- keycloakUri,
263
- https: Boolean(options.https),
264
- proxyVerbose
265
- });
266
- }
267
- }
268
-
269
- registry.forEach(cb => cb({
270
- app,
271
- options,
272
- compiler,
273
- config: standaloneConfig
274
- }));
263
+ if (chromePath) {
264
+ registerChrome({
265
+ app,
266
+ chromePath,
267
+ keycloakUri,
268
+ https: Boolean(options.https),
269
+ proxyVerbose,
270
+ });
275
271
  }
276
- };
272
+ }
273
+
274
+ registry.forEach((cb) =>
275
+ cb({
276
+ app,
277
+ options,
278
+ compiler,
279
+ config: standaloneConfig,
280
+ })
281
+ );
282
+ },
283
+ };
277
284
  };
278
-
@@ -7,11 +7,14 @@ const glob = require('glob');
7
7
  * @returns {Object}
8
8
  */
9
9
  const searchIgnoredStyles = (root) => {
10
- const modulesPath = path.join(root, 'node_modules/@patternfly/react-styles');
11
- return glob.sync(`${modulesPath}/**/*.css`).reduce((acc, curr) => ({
12
- ...acc,
13
- [curr]: false
14
- }), {});
10
+ const modulesPath = path.join(root, 'node_modules/@patternfly/react-styles');
11
+ return glob.sync(`${modulesPath}/**/*.css`).reduce(
12
+ (acc, curr) => ({
13
+ ...acc,
14
+ [curr]: false,
15
+ }),
16
+ {}
17
+ );
15
18
  };
16
19
 
17
20
  module.exports = searchIgnoredStyles;
@@ -3,33 +3,33 @@ const fs = require('fs');
3
3
  const concurrently = require('concurrently');
4
4
 
5
5
  function federate(argv, cwd) {
6
- let configPath = argv.config;
7
- const WEBPACK_PATH = path.resolve(cwd, './node_modules/.bin/webpack');
8
- const HTTP_SERVER_PATH = path.resolve(cwd, './node_modules/.bin/http-server');
9
- if (typeof configPath !== 'string') {
10
- console.error('Missing webpack config path');
11
- process.exit(1);
12
- }
6
+ let configPath = argv.config;
7
+ const WEBPACK_PATH = path.resolve(cwd, './node_modules/.bin/webpack');
8
+ const HTTP_SERVER_PATH = path.resolve(cwd, './node_modules/.bin/http-server');
9
+ if (typeof configPath !== 'string') {
10
+ console.error('Missing webpack config path');
11
+ process.exit(1);
12
+ }
13
13
 
14
- configPath = path.join(cwd, configPath);
14
+ configPath = path.join(cwd, configPath);
15
15
 
16
- try {
17
- fs.statSync(configPath);
18
- let config = require(configPath);
19
- if (typeof config === 'function') {
20
- config = config(process.env);
21
- }
16
+ try {
17
+ fs.statSync(configPath);
18
+ let config = require(configPath);
19
+ if (typeof config === 'function') {
20
+ config = config(process.env);
21
+ }
22
22
 
23
- const outputPath = config.output.path;
23
+ const outputPath = config.output.path;
24
24
 
25
- concurrently([
26
- `${WEBPACK_PATH} --config ${configPath} --watch --output-path ${path.join(outputPath, config.output.publicPath)}`,
27
- `${HTTP_SERVER_PATH} ${outputPath} -p ${argv.port || 8003} -c-1`
28
- ]);
29
- } catch (error) {
30
- console.error(error);
31
- process.exit(1);
32
- }
25
+ concurrently([
26
+ `${WEBPACK_PATH} --config ${configPath} --watch --output-path ${path.join(outputPath, config.output.publicPath)}`,
27
+ `${HTTP_SERVER_PATH} ${outputPath} -p ${argv.port || 8003} -c-1`,
28
+ ]);
29
+ } catch (error) {
30
+ console.error(error);
31
+ process.exit(1);
32
+ }
33
33
  }
34
34
 
35
35
  module.exports = federate;
package/serveLocalFile.js CHANGED
@@ -1,18 +1,18 @@
1
1
  /* eslint-disable no-console */
2
2
  function serveLocalFile(url, path, target = 'https://ci.cloud.redhat.com') {
3
- console.warn('\x1b[33mserveLocalFile is deprecated in favor of hooking into webpack-dev-server\'s express app.');
4
- console.warn('See https://github.com/RedHatInsights/frontend-components/blob/master/packages/config/README.md#standalone');
5
- return {
6
- context: (path) => path.includes(url),
7
- target,
8
- secure: false,
9
- changeOrigin: true,
10
- autoRewrite: true,
11
- selfHandleResponse: true,
12
- onProxyReq: (_pr, _req, res) => {
13
- res.sendFile(path);
14
- }
15
- };
3
+ console.warn("\x1b[33mserveLocalFile is deprecated in favor of hooking into webpack-dev-server's express app.");
4
+ console.warn('See https://github.com/RedHatInsights/frontend-components/blob/master/packages/config/README.md#standalone');
5
+ return {
6
+ context: (path) => path.includes(url),
7
+ target,
8
+ secure: false,
9
+ changeOrigin: true,
10
+ autoRewrite: true,
11
+ selfHandleResponse: true,
12
+ onProxyReq: (_pr, _req, res) => {
13
+ res.sendFile(path);
14
+ },
15
+ };
16
16
  }
17
17
 
18
18
  module.exports = serveLocalFile;