@oroinc/oro-webpack-config-builder 5.1.0-alpha9 → 5.1.0-lts001

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +1 -1
  2. package/error-handler.js +95 -0
  3. package/loader/config-loader.js +1 -2
  4. package/loader/inject-loader/LICENSE.md +21 -0
  5. package/loader/inject-loader/README.md +54 -0
  6. package/loader/inject-loader/index.js +10 -0
  7. package/loader/inject-loader/injectify.js +66 -0
  8. package/loader/inject-loader/package.json +55 -0
  9. package/loader/inject-loader/wrapper_template.js +32 -0
  10. package/modules-config/layout-modules-config-loader.js +66 -2
  11. package/modules-config/modules-config-loader.js +52 -19
  12. package/oro-webpack-config.js +410 -299
  13. package/package.json +37 -38
  14. package/plugin/logs/after-webpack-logs-plugin.js +25 -0
  15. package/style/admin-style-loader.js +4 -3
  16. package/style/layout-style-loader.js +3 -3
  17. package/style/style-loader.js +52 -7
  18. package/theme-config-factory.js +45 -6
  19. package/utils.js +30 -0
  20. package/validation/assets-validator.js +104 -0
  21. package/validation/errors/assets-input-file-error.js +24 -0
  22. package/validation/errors/assets-schema-error.js +40 -0
  23. package/validation/errors/base-error.js +37 -0
  24. package/validation/errors/jsmodules-extra-modules-error.js +22 -0
  25. package/validation/errors/jsmodules-schema-error.js +40 -0
  26. package/validation/errors/styles-error.js +24 -0
  27. package/validation/index.js +36 -0
  28. package/validation/jsmodules-validator.js +53 -0
  29. package/validation/schema-validator.js +62 -0
  30. package/validation/schemas/assets-schema-full.js +22 -0
  31. package/validation/schemas/assets-schema.js +32 -0
  32. package/validation/schemas/jsmodules-schema-full.js +11 -0
  33. package/validation/schemas/jsmodules-schema.js +76 -0
  34. package/writer/configs-file-writer.js +1 -1
  35. package/writer/dynamic-imports-file-writer.js +3 -3
  36. package/writer/scss-entry-point-file-writer.js +1 -1
package/package.json CHANGED
@@ -1,49 +1,48 @@
1
1
  {
2
2
  "name": "@oroinc/oro-webpack-config-builder",
3
- "version": "5.1.0-alpha9",
3
+ "version": "5.1.0-lts001",
4
4
  "author": "Oro, Inc (https://www.oroinc.com)",
5
5
  "license": "MIT",
6
6
  "description": "An integration of OroPlatform based applications with the Webpack.",
7
7
  "main": "oro-webpack-config.js",
8
8
  "dependencies": {
9
- "@babel/core": "^7.10.4",
10
- "@babel/plugin-transform-runtime": "^7.10.4",
11
- "@babel/preset-env": "^7.10.4",
12
- "autoprefixer": "^9.8.6",
13
- "babel-loader": "^8.1.0",
14
- "bindings": "^1.5.0",
15
- "css-loader": "^5.0.2",
16
- "css-minimizer-webpack-plugin": "^1.2.0",
17
- "deepmerge": "^4.2.2",
18
- "exports-loader": "^2.0.0",
19
- "expose-loader": "^2.0.0",
20
- "extract-loader": "^5.1.0",
21
- "file-loader": "^6.2.0",
22
- "happypack": "^5.0.1",
23
- "html-webpack-plugin": "^5.2.0",
24
- "imports-loader": "^2.0.0",
25
- "js-yaml": "^4.0.0",
26
- "mini-css-extract-plugin": "^1.3.8",
27
- "minimist": "^1.2.3",
28
- "nan": "^2.14.2",
9
+ "@babel/core": "~7.21.3",
10
+ "@babel/plugin-transform-runtime": "~7.21.0",
11
+ "@babel/preset-env": "~7.20.2",
12
+ "autoprefixer": "~10.4.13",
13
+ "babel-loader": "~9.1.0",
14
+ "bindings": "~1.5.0",
15
+ "css-loader": "^6.7.3",
16
+ "css-minimizer-webpack-plugin": "~4.2.2",
17
+ "deepmerge": "~4.3.1",
18
+ "exports-loader": "~4.0.0",
19
+ "expose-loader": "~4.1.0",
20
+ "file-loader": "~6.2.0",
21
+ "html-webpack-plugin": "~5.5.0",
22
+ "imports-loader": "~4.0.1",
23
+ "js-yaml": "~4.1.0",
24
+ "mini-css-extract-plugin": "~2.7.1",
25
+ "minimist": "~1.2.7",
26
+ "nan": "~2.17.0",
29
27
  "path": "0.12.7",
30
- "postcss": "^8.2.9",
31
- "postcss-loader": "^5.0.0",
32
- "printf": "^0.6.0",
33
- "resolve-url-loader": "^3.1.2",
34
- "rtlcss-webpack-plugin": "^4.0.6",
35
- "sass": "^1.32.8",
36
- "sass-loader": "^11.0.1",
37
- "style-loader": "^2.0.0",
38
- "terser": "^5.6.0",
28
+ "postcss": "~8.4.19",
29
+ "postcss-loader": "~7.1.0",
30
+ "printf": "~0.6.0",
31
+ "resolve-url-loader": "^5.0.0",
32
+ "rtlcss-webpack-plugin": "~4.0.6",
33
+ "sass": "~1.59.3",
34
+ "sass-loader": "~13.2.0",
35
+ "schema-utils": "^4.0.0",
36
+ "style-loader": "~3.3.1",
37
+ "terser": "~5.16.1",
39
38
  "text-loader": "0.0.1",
40
- "underscore": "^1.10.2",
41
- "url-loader": "^4.1.1",
42
- "webpack": "^5.23.0",
43
- "webpack-bundle-analyzer": "^4.4.0",
44
- "webpack-cli": "^4.5.0",
45
- "webpack-dev-server": "^3.11.0",
46
- "webpack-merge": "^5.7.3",
47
- "wildcard": "^2.0.0"
39
+ "underscore": "1.13.*",
40
+ "url-loader": "~4.1.1",
41
+ "webpack": "~5.76.3",
42
+ "webpack-bundle-analyzer": "~4.8.0",
43
+ "webpack-cli": "~5.0.0",
44
+ "webpack-dev-server": "^4.11.1",
45
+ "webpack-merge": "~5.8.0",
46
+ "wildcard": "~2.0.0"
48
47
  }
49
48
  }
@@ -0,0 +1,25 @@
1
+ const {once} = require('underscore');
2
+
3
+ class AfterWebpackLogsPlugin {
4
+ /**
5
+ * @param {function} afterLogsCb
6
+ */
7
+ constructor(afterLogsCb) {
8
+ if (typeof afterLogsCb !== 'function') {
9
+ throw new Error('The "afterLogsCb" arg should be a function');
10
+ }
11
+ this._afterLogsCb = once(afterLogsCb);
12
+ }
13
+
14
+ apply(compiler) {
15
+ compiler.hooks.done.tap('AfterWebpackLogsPlugin', stats => {
16
+ const compilerStats = stats;
17
+ stats.compilation.hooks.statsPrinter.tap('AfterWebpackLogsPlugin', stats => {
18
+ // Making logs to be after all webpack logs in the console
19
+ setImmediate(() => this._afterLogsCb(compilerStats));
20
+ });
21
+ });
22
+ }
23
+ }
24
+
25
+ module.exports = AfterWebpackLogsPlugin;
@@ -3,19 +3,20 @@ const StyleLoader = require('./style-loader');
3
3
 
4
4
  class AdminStyleLoader extends StyleLoader {
5
5
  /**
6
- * @inheritDoc
6
+ * @inheritdoc
7
7
  */
8
8
  _fetchThemeConfig(themeName) {
9
9
  const {rtl_support: rtlSupport = false, styles: extraThemeConfig} =
10
10
  this._configLoader.loadConfig(themeName, 'Resources/public/themes/' + themeName + '/settings.yml');
11
11
  const baseThemeConfig = this._configLoader.loadConfig(themeName, 'Resources/config/oro/assets.yml');
12
+ const appRootExtraConfig = this._configLoader.loadConfig(themeName, 'config/oro/assets.yml');
12
13
  /** @type {Object.<string, ThemeGroupConfig>} */
13
- const themeConfig = merge({}, baseThemeConfig, extraThemeConfig);
14
+ const themeConfig = merge(baseThemeConfig, appRootExtraConfig, extraThemeConfig);
14
15
 
15
16
  return {
16
17
  themeConfig,
17
18
  settings: {rtlSupport}
18
- }
19
+ };
19
20
  }
20
21
  }
21
22
 
@@ -1,8 +1,8 @@
1
1
  const StyleLoader = require('./style-loader');
2
2
 
3
- class LayoutStyleLoader extends StyleLoader {
3
+ class LayoutStyleLoader extends StyleLoader {
4
4
  /**
5
- * @inheritDoc
5
+ * @inheritdoc
6
6
  */
7
7
  _fetchThemeConfig(themeName) {
8
8
  const {rtl_support: rtlSupport = false} = this._configLoader.themes[themeName];
@@ -12,7 +12,7 @@ class LayoutStyleLoader extends StyleLoader {
12
12
  return {
13
13
  themeConfig,
14
14
  settings: {rtlSupport}
15
- }
15
+ };
16
16
  }
17
17
  }
18
18
 
@@ -1,6 +1,9 @@
1
1
  const path = require('path');
2
2
  const wildcard = require('wildcard');
3
- const _ = require('underscore')
3
+ const _ = require('underscore');
4
+ const {isProdMode} = require('../utils');
5
+ const {assetsValidation} = require('../validation');
6
+ const StylesError = require('../validation/errors/styles-error');
4
7
 
5
8
  /**
6
9
  * @typedef ThemeGroupConfig
@@ -29,16 +32,24 @@ class StyleLoader {
29
32
  getThemeEntryPoints(theme, buildPath) {
30
33
  const {themeConfig, settings = {}} = this._fetchThemeConfig(theme);
31
34
 
35
+ assetsValidation.checkFullSchema(themeConfig, this._configLoader.processedFiles, theme);
36
+
32
37
  const entryPoints = {};
33
38
  const writingOptions = {};
34
39
  for (const [group, config] of Object.entries(themeConfig)) {
35
40
  let {inputs, entries = [], output, auto_rtl_inputs: rtlMasks = []} = config;
36
- if (output === undefined) {
37
- throw new Error('"output" for "' + group + '" group in theme "' + theme + '" is not defined');
41
+
42
+ if (isProdMode() && output === void 0) {
43
+ throw new StylesError('output', group, theme);
44
+ }
45
+
46
+ if (isProdMode() && inputs === void 0) {
47
+ throw new StylesError('inputs', group, theme);
38
48
  }
39
49
 
40
50
  inputs = this._overrideInputs(inputs);
41
51
  inputs = this._sortInputs(inputs);
52
+ inputs = this._applyInputsBasePathPrefix(inputs);
42
53
 
43
54
  if (settings.rtlSupport) {
44
55
  writingOptions.ignoreRTLInputs = _.difference(inputs, this._matchInputs(rtlMasks, inputs));
@@ -48,7 +59,7 @@ class StyleLoader {
48
59
  const filePath = path.join(buildPath, output);
49
60
  entryPoints[entryPointName] = [
50
61
  ...entries,
51
- this._entryPointFileWriter.write('./../../../', inputs, filePath, writingOptions)
62
+ this._entryPointFileWriter.write('./../../', inputs, filePath, writingOptions)
52
63
  ];
53
64
  }
54
65
  return entryPoints;
@@ -83,7 +94,7 @@ class StyleLoader {
83
94
  const oldInputIndex = mappedInputs.findIndex(item => item === oldInput);
84
95
 
85
96
  if (oldInputIndex === -1) {
86
- // old input does not exists any more
97
+ // old input does not exist anymore
87
98
  mappedInputs.push(newInput);
88
99
  } else if (newInput) {
89
100
  // replace input
@@ -105,20 +116,33 @@ class StyleLoader {
105
116
  * @protected
106
117
  */
107
118
  _sortInputs(inputs) {
119
+ const primarySettingsInputs = [];
108
120
  const settingsInputs = [];
121
+ const primaryVariablesInputs = [];
109
122
  const variablesInputs = [];
110
123
  const restInputs = [];
111
124
 
112
125
  inputs.forEach(input => {
113
- if (input.indexOf('/settings/') > 0) {
126
+ if (input.indexOf('/settings/primary-settings') > 0) {
127
+ primarySettingsInputs.push(input);
128
+ } else if (input.indexOf('/settings/') > 0) {
114
129
  settingsInputs.push(input);
130
+ } else if (input.indexOf('/variables/primary-variables') > 0) {
131
+ primaryVariablesInputs.push(input);
115
132
  } else if (input.indexOf('/variables/') > 0) {
116
133
  variablesInputs.push(input);
117
134
  } else {
118
135
  restInputs.push(input);
119
136
  }
120
137
  });
121
- return [...settingsInputs, ...variablesInputs, ...restInputs];
138
+
139
+ return [
140
+ ...primarySettingsInputs,
141
+ ...settingsInputs,
142
+ ...primaryVariablesInputs,
143
+ ...variablesInputs,
144
+ ...restInputs
145
+ ];
122
146
  }
123
147
 
124
148
  /**
@@ -130,6 +154,7 @@ class StyleLoader {
130
154
  * @protected
131
155
  */
132
156
  _matchInputs(masks, inputs) {
157
+ masks = this._applyInputsBasePathPrefix(masks);
133
158
  masks = masks.map(mask => wildcard(mask));
134
159
 
135
160
  const whiteListedInputs = masks.reduce((include, mask) => {
@@ -139,6 +164,26 @@ class StyleLoader {
139
164
 
140
165
  return _.unique(whiteListedInputs);
141
166
  }
167
+
168
+ /**
169
+ * Considering base path as application's root.
170
+ * Bundles based *.scss sources go with '../' prefix.
171
+ *
172
+ * @param {string[]} inputs
173
+ * @private
174
+ */
175
+ _applyInputsBasePathPrefix(inputs) {
176
+ const processedInputs = [];
177
+
178
+ inputs.forEach(input => {
179
+ if (input.indexOf('bundles') === 0) {
180
+ input = '../' + input;
181
+ }
182
+ processedInputs.push(input);
183
+ });
184
+
185
+ return processedInputs;
186
+ }
142
187
  }
143
188
 
144
189
  module.exports = StyleLoader;
@@ -1,3 +1,5 @@
1
+ const JSModulesExtraModulesError = require('./validation/errors/jsmodules-extra-modules-error');
2
+
1
3
  class ThemeConfigFactory {
2
4
  /**
3
5
  * @param {ModulesConfigLoader} configLoader
@@ -11,22 +13,59 @@ class ThemeConfigFactory {
11
13
  this._appModulesFileWriter = appModulesFileWriter;
12
14
  this._configsFileWriter = configsFileWriter;
13
15
  }
14
-
15
16
  /**
16
17
  * @param {string} theme Theme name
17
- * @param {string} buildPath Path to theme build folder
18
18
  * @param {string|string[]} configFilepath Path (or paths with fallback) to yaml config file in a bundle
19
- * @return {Object} List of Webpack entry-points
19
+ * @return {Object} Merged Configs loaded from all the bundles Yaml files matched by filePath
20
+ */
21
+ loadConfig(theme, configFilepath) {
22
+ return this._configLoader.loadConfig(theme, configFilepath);
23
+ }
24
+
25
+ extendConfig(baseConfig, extraConfig) {
26
+ const {
27
+ aliases = {},
28
+ configs,
29
+ map = {},
30
+ shim = {}
31
+ } = baseConfig;
32
+
33
+ const {
34
+ ['app-modules']: appModules,
35
+ ['dynamic-imports']: dynamicImports,
36
+ entry,
37
+ ...rest
38
+ } = extraConfig;
39
+
40
+ const beyondKeys = Object.keys(rest);
41
+ if (beyondKeys.length) {
42
+ throw new JSModulesExtraModulesError(beyondKeys);
43
+ }
44
+
45
+ return {
46
+ aliases,
47
+ 'app-modules': appModules,
48
+ configs,
49
+ 'dynamic-imports': dynamicImports,
50
+ entry,
51
+ map,
52
+ shim
53
+ };
54
+ }
55
+
56
+ /**
57
+ * @param {string} buildPath Path to theme build folder
58
+ * @param {Object} jsModulesConfig configuration loaded from jsmodules files and merged together
59
+ * @return {Object} webpack configuration fragment
20
60
  */
21
- create(theme, buildPath, configFilepath) {
22
- const jsModulesConfig = this._configLoader.loadConfig(theme, configFilepath);
61
+ create(buildPath, jsModulesConfig) {
23
62
  const {
24
63
  entry,
25
64
  map = {},
26
65
  shim = {},
27
66
  configs,
28
67
  aliases = {},
29
- ['app-modules']: appModules,
68
+ ['app-modules']: appModules = [],
30
69
  ['dynamic-imports']: dynamicImports
31
70
  } = jsModulesConfig;
32
71
 
package/utils.js ADDED
@@ -0,0 +1,30 @@
1
+ let prodMode;
2
+ let verboseMode;
3
+
4
+ module.exports = {
5
+ isVerboseMode() {
6
+ if (verboseMode === void 0) {
7
+ verboseMode = process.argv.filter(arg => {
8
+ // Depending on how the command was run (-v, -vv, -vvv, --verbose) -
9
+ // arguments can be present in different formats: stats=normal, stats=detailed, stats=verbose, verbose
10
+ return arg.search(/^verbose|(^stats=(normal|detailed|verbose))/) !== -1;
11
+ }).length > 0;
12
+ }
13
+
14
+ return verboseMode;
15
+ },
16
+ isProdMode() {
17
+ if (prodMode !== void 0) {
18
+ return prodMode;
19
+ }
20
+
21
+ process.argv.forEach(arg => {
22
+ if (prodMode) {
23
+ return;
24
+ }
25
+ prodMode = ['--mode=production', '--env=prod'].some(item => item === arg);
26
+ });
27
+
28
+ return prodMode;
29
+ }
30
+ };
@@ -0,0 +1,104 @@
1
+ const {isProdMode} = require('../utils');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const schema = require('./schemas/assets-schema');
5
+ const fullSchema = require('./schemas/assets-schema-full');
6
+ const schemaValidator = require('./schema-validator');
7
+ const EventEmitter = require('events');
8
+ const emitter = new EventEmitter();
9
+ const AssetsSchemaError = require('./errors/assets-schema-error');
10
+ const AssetsInputFileError = require('./errors/assets-input-file-error');
11
+
12
+ module.exports = Object.assign({}, schemaValidator, {
13
+ emitter,
14
+
15
+ /**
16
+ * @param {string} filePath
17
+ * @param {Object} doc
18
+ * @param {string} theme
19
+ * @returns {boolean|undefined}
20
+ */
21
+ checkSchema(filePath, doc, theme) {
22
+ if (isProdMode()) {
23
+ return;
24
+ }
25
+ const result = this.validateSchema(schema, doc);
26
+
27
+ if (!result.valid) {
28
+ const error = new AssetsSchemaError(result.formattedError, [filePath], theme);
29
+
30
+ this.emitter.emit('error', error);
31
+ }
32
+
33
+ return result.valid;
34
+ },
35
+
36
+ /**
37
+ * @param {Object} doc
38
+ * @param {Array} files
39
+ * @param {string} theme
40
+ * @returns {boolean|undefined}
41
+ */
42
+ checkFullSchema(doc, files = [], theme) {
43
+ if (isProdMode()) {
44
+ return;
45
+ }
46
+ const result = this.validateSchema(fullSchema, doc);
47
+
48
+ if (!result.valid) {
49
+ const error = new AssetsSchemaError(result.formattedError, files, theme);
50
+
51
+ this.emitter.emit('error', error);
52
+ }
53
+
54
+ return result.valid;
55
+ },
56
+
57
+ /**
58
+ * @param {string} filePath
59
+ * @param {Object} doc
60
+ * @param {string} theme
61
+ * @returns {boolean|undefined}
62
+ */
63
+ checkInputsExist(filePath, doc, theme) {
64
+ if (isProdMode()) {
65
+ return;
66
+ }
67
+
68
+ let valid = true;
69
+ for (const [, props] of Object.entries(doc)) {
70
+ if (!Array.isArray(props.inputs)) {
71
+ continue;
72
+ }
73
+
74
+ const files = [];
75
+ props.inputs.forEach(input => {
76
+ if (typeof input === 'object') {
77
+ const newPath = Object.values(input)[0];
78
+
79
+ if (newPath === '~') {
80
+ return;
81
+ }
82
+ input = newPath;
83
+ }
84
+
85
+ const fullBasePath = path.resolve(input);
86
+ const fullPath = path.resolve(this._publicPath + input);
87
+ // skip the path to global node modules,
88
+ // e.g. '~bootstrap/scss/bootstrap'
89
+ if (!input.startsWith('~') && !fs.existsSync(fullPath) && !fs.existsSync(fullBasePath)) {
90
+ files.push(input);
91
+ }
92
+ });
93
+ if (files.length) {
94
+ valid = false;
95
+ files.forEach(notExistFile => {
96
+ const error = new AssetsInputFileError(notExistFile, filePath);
97
+
98
+ this.emitter.emit('error', error);
99
+ });
100
+ }
101
+ }
102
+ return valid;
103
+ }
104
+ });
@@ -0,0 +1,24 @@
1
+ const BaseError = require('./base-error');
2
+
3
+ class AssetsInputFileError extends BaseError {
4
+ /**
5
+ * @example
6
+ * Invalid styles config: input file does not exist /scss/test.scss
7
+ * at /config/assets.yml
8
+ * Please, find more information in the documentation https://doc.oroinc.com/...
9
+ *
10
+ * @param {string} notExistFile
11
+ * @param {string} path
12
+ */
13
+ constructor(notExistFile, path) {
14
+ const msg = `input file does not exist: ${notExistFile}\nat ${path}:1`;
15
+
16
+ super(msg);
17
+
18
+ this.name = 'Invalid styles config';
19
+ this.docLink =
20
+ 'https://doc.oroinc.com/backend/bundles/platform/AssetBundle/#load-scss-or-css-files-from-the-bundle';
21
+ }
22
+ }
23
+
24
+ module.exports = AssetsInputFileError;
@@ -0,0 +1,40 @@
1
+ const BaseError = require('./base-error');
2
+
3
+ class AssetsSchemaError extends BaseError {
4
+ /**
5
+ * @example
6
+ * Invalid styles config: the "assets.yml" in the "default" theme file does not match the API schema.
7
+ * styles.inputs[0] should be: string | object
8
+ * at /config/assets.yml
9
+ * Please, find more information in the documentation https://doc.oroinc.com/...
10
+ *
11
+ * @example
12
+ * Invalid styles config: the "assets.yml" file the "default" theme does not match the API schema.
13
+ * styles misses the property 'output'.
14
+ * List of processed files for the "default" theme:
15
+ * /default/config/assets.yml
16
+ * /default/config/assets.yml
17
+ * Please, find more information in the documentation https://doc.oroinc.com/...
18
+ *
19
+ * @param {string} reason
20
+ * @param {Array} files
21
+ * @param {string} theme
22
+ */
23
+ constructor(reason, files, theme) {
24
+ let msg = `the "assets.yml" file in the "${theme}" theme does not match the API schema.\n${reason}`;
25
+
26
+ const filesListMsg = BaseError.generateFilesListMsg(files, theme);
27
+
28
+ if (filesListMsg.length) {
29
+ msg = `${msg}\n${filesListMsg}`;
30
+ }
31
+
32
+ super(msg);
33
+
34
+ this.name = 'Invalid styles config';
35
+ this.docLink =
36
+ 'https://doc.oroinc.com/backend/bundles/platform/AssetBundle/#load-scss-or-css-files-from-the-bundle';
37
+ }
38
+ }
39
+
40
+ module.exports = AssetsSchemaError;
@@ -0,0 +1,37 @@
1
+ const {isVerboseMode} = require('../../utils');
2
+
3
+ class BaseError extends Error {
4
+ /**
5
+ * Prepares documentation phrase
6
+ * @returns {string}
7
+ */
8
+ get extra() {
9
+ return this.docLink ? `Please, find more information in the documentation ${this.docLink}` : '';
10
+ }
11
+
12
+ /**
13
+ * Creates an instance of BaseError
14
+ * @param {string} message error message
15
+ */
16
+ constructor(message) {
17
+ super(message);
18
+ }
19
+
20
+ /**
21
+ * Creates a part of message about processed files
22
+ * @param {Array} files
23
+ * @param {string} theme
24
+ * @returns {string}
25
+ */
26
+ static generateFilesListMsg(files, theme) {
27
+ if (files.length === 1) {
28
+ return `at ${files[0]}:1`;
29
+ } else if (isVerboseMode()) {
30
+ return `List of processed files for the "${theme}" theme:\n ${files.join('\n ')}`;
31
+ }
32
+
33
+ return '';
34
+ }
35
+ }
36
+
37
+ module.exports = BaseError;
@@ -0,0 +1,22 @@
1
+ const BaseError = require('./base-error');
2
+
3
+ class JsmodulesExtraModulesError extends BaseError {
4
+ /**
5
+ * @example
6
+ * Failed assembly JS: sections ["shim"] are not allowed in extra js build definition.
7
+ * Please, find more information in the documentation https://doc.oroinc.com/...
8
+ *
9
+ * @param {Array} parts
10
+ */
11
+ constructor(parts) {
12
+ const msg = `sections ["${parts.join('", "')}"] are not allowed in extra js build definition.`;
13
+
14
+ super(msg);
15
+
16
+ this.name = 'Failed assembly JS';
17
+ this.docLink =
18
+ 'https://doc.oroinc.com/master/frontend/storefront/how-to/how-to-create-extra-js-build-for-landing-page';
19
+ }
20
+ }
21
+
22
+ module.exports = JsmodulesExtraModulesError;
@@ -0,0 +1,40 @@
1
+ const BaseError = require('./base-error');
2
+
3
+ class JSModulesSchemaError extends BaseError {
4
+ /**
5
+ * @example
6
+ * Invalid JS config: the "jsmodules.yml" files in the "default" theme do not match the API schema.
7
+ * has an unknown property 'rest'.
8
+ * at default/config/jsmodules.yml
9
+ * Please, find more information in the documentation https://doc.oroinc.com/...
10
+ *
11
+ * @example
12
+ * Invalid JS config: the "jsmodules.yml" files in the "default" theme do not match the API schema.
13
+ * misses the property 'entry'.
14
+ * List of processed files for the "default" theme:
15
+ * /default/config/jsmodules.yml
16
+ * /default/config/jsmodules.yml
17
+ * Please, find more information in the documentation https://doc.oroinc.com/...
18
+ *
19
+ * @param {string} reason
20
+ * @param {Array} files
21
+ * @param {string} theme
22
+ */
23
+ constructor(reason, files, theme) {
24
+ let msg = `the "jsmodules.yml" files in the "${theme}" theme do not match the API schema.\n${reason}`;
25
+
26
+ const filesListMsg = BaseError.generateFilesListMsg(files, theme);
27
+
28
+ if (filesListMsg.length) {
29
+ msg = `${msg}\n${filesListMsg}`;
30
+ }
31
+
32
+ super(msg);
33
+
34
+ this.name = 'Invalid JS config';
35
+ this.docLink =
36
+ 'https://doc.oroinc.com/backend/bundles/platform/AssetBundle/#create-jsmodules-yml-configuration';
37
+ }
38
+ }
39
+
40
+ module.exports = JSModulesSchemaError;