@bigcommerce/stencil-cli 3.13.0 → 4.1.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/CHANGELOG.md +25 -0
- package/README.md +2 -2
- package/bin/stencil-bundle.js +3 -6
- package/bin/stencil-debug.js +17 -0
- package/bin/stencil-download.js +3 -7
- package/bin/stencil-init.js +3 -6
- package/bin/stencil-pull.js +3 -7
- package/bin/stencil-push.js +3 -7
- package/bin/stencil-start.js +3 -6
- package/lib/BuildConfigManager.js +4 -1
- package/lib/StencilCLISettings.js +28 -0
- package/lib/StencilDebug.js +113 -0
- package/lib/bundle-validator.js +84 -12
- package/lib/cliCommon.js +60 -0
- package/lib/css/compile.js +6 -3
- package/lib/utils/NetworkUtils.js +12 -0
- package/package-lock.json +2548 -2923
- package/package.json +14 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
### Draft
|
|
2
2
|
|
|
3
|
+
### 4.1.1 (2022-05-24)
|
|
4
|
+
|
|
5
|
+
- fix: strf-9781 Bump dev packages for linting ([932](https://github.com/bigcommerce/stencil-cli/pull/932))
|
|
6
|
+
- fix: STRF-9781 Bump axios, @ocktokit/rest and browser-sync ([931](https://github.com/bigcommerce/stencil-cli/pull/931))
|
|
7
|
+
- fix: STRF-9781 Bump async and confidence ([929](https://github.com/bigcommerce/stencil-cli/pull/929))
|
|
8
|
+
- fix: STRF-9781 Bump simple-git ([928](https://github.com/bigcommerce/stencil-cli/pull/928))
|
|
9
|
+
|
|
10
|
+
### 4.1.0 (2022-04-28)
|
|
11
|
+
|
|
12
|
+
- feat: strf-9749 Update Stencil Cli to use node-sass latest by default ([923](https://github.com/bigcommerce/stencil-cli/pull/923))
|
|
13
|
+
New option:`--use-old-node-sass-fork (--oldn)` to bypass error warning (in case it exist) using latest node-sass version.
|
|
14
|
+
Soon, it node sass fork will be deprecated and it won't be possible to compile with it.
|
|
15
|
+
|
|
16
|
+
- feat: STRF-9757 Introduced "stencil debug" ([918](https://github.com/bigcommerce/stencil-cli/pull/918))
|
|
17
|
+
|
|
18
|
+
Available options: --output [filename] (-o)
|
|
19
|
+
If not provided, will be logged to std
|
|
20
|
+
|
|
21
|
+
- feat: STRF-9741 Verbose network requests logging in Stencil CLI by default ([914](https://github.com/bigcommerce/stencil-cli/pull/914))
|
|
22
|
+
Introduced `--no-verbose` option on all commands to supress verbose network requests logging.
|
|
23
|
+
|
|
24
|
+
### 4.0.0 (2022-04-11)
|
|
25
|
+
|
|
26
|
+
- Added support for node 14 and drop node 10
|
|
27
|
+
|
|
3
28
|
### 3.13.0 (2022-04-08)
|
|
4
29
|
|
|
5
30
|
- feat: strf-9718 Add OAuth token to headers ([903](https://github.com/bigcommerce/stencil-cli/pull/903))
|
package/README.md
CHANGED
|
@@ -8,8 +8,8 @@ The BigCommerce server emulator for local theme development.
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
10
10
|
_Note: Stencil requires the Node.js runtime environment,
|
|
11
|
-
version
|
|
12
|
-
We do not yet have support for versions greater than Node
|
|
11
|
+
version 12.x and 14.x (Recommended) are supported.
|
|
12
|
+
We do not yet have support for versions greater than Node 14._
|
|
13
13
|
|
|
14
14
|
Run `npm install -g @bigcommerce/stencil-cli`.
|
|
15
15
|
|
package/bin/stencil-bundle.js
CHANGED
|
@@ -7,7 +7,7 @@ const { THEME_PATH, PACKAGE_INFO } = require('../constants');
|
|
|
7
7
|
const ThemeConfig = require('../lib/theme-config');
|
|
8
8
|
const Bundle = require('../lib/stencil-bundle');
|
|
9
9
|
const { printCliResultErrorAndExit } = require('../lib/cliCommon');
|
|
10
|
-
const {
|
|
10
|
+
const { prepareCommand } = require('../lib/cliCommon');
|
|
11
11
|
const BuildConfigManager = require('../lib/BuildConfigManager');
|
|
12
12
|
|
|
13
13
|
program
|
|
@@ -28,16 +28,13 @@ program
|
|
|
28
28
|
'-t, --timeout [timeout]',
|
|
29
29
|
'Set a timeout for the bundle operation. Default is 20 secs',
|
|
30
30
|
'60',
|
|
31
|
-
)
|
|
32
|
-
.parse(process.argv);
|
|
31
|
+
);
|
|
33
32
|
|
|
34
|
-
const cliOptions = program
|
|
33
|
+
const cliOptions = prepareCommand(program);
|
|
35
34
|
const themeConfig = ThemeConfig.getInstance(THEME_PATH);
|
|
36
35
|
|
|
37
36
|
async function run() {
|
|
38
37
|
try {
|
|
39
|
-
checkNodeVersion();
|
|
40
|
-
|
|
41
38
|
if (cliOptions.dest === true) {
|
|
42
39
|
throw new Error('You have to specify a value for -d or --dest'.red);
|
|
43
40
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
require('colors');
|
|
4
|
+
const program = require('../lib/commander');
|
|
5
|
+
|
|
6
|
+
const StencilDebug = require('../lib/StencilDebug');
|
|
7
|
+
const { PACKAGE_INFO } = require('../constants');
|
|
8
|
+
const { printCliResultErrorAndExit } = require('../lib/cliCommon');
|
|
9
|
+
|
|
10
|
+
program
|
|
11
|
+
.version(PACKAGE_INFO.version)
|
|
12
|
+
.option('-o, --output [filename]', 'If provided will write to file')
|
|
13
|
+
.parse(process.argv);
|
|
14
|
+
|
|
15
|
+
const cliOptions = program.opts();
|
|
16
|
+
|
|
17
|
+
new StencilDebug().run(cliOptions).catch(printCliResultErrorAndExit);
|
package/bin/stencil-download.js
CHANGED
|
@@ -6,21 +6,17 @@ const program = require('../lib/commander');
|
|
|
6
6
|
|
|
7
7
|
const { PACKAGE_INFO } = require('../constants');
|
|
8
8
|
const stencilDownload = require('../lib/stencil-download');
|
|
9
|
-
const {
|
|
9
|
+
const { prepareCommand } = require('../lib/cliCommon');
|
|
10
10
|
const { printCliResultErrorAndExit } = require('../lib/cliCommon');
|
|
11
11
|
|
|
12
12
|
program
|
|
13
13
|
.version(PACKAGE_INFO.version)
|
|
14
|
-
.option('-h, --host [hostname]', 'specify the api host')
|
|
15
14
|
.option('-f, --file [filename]', 'specify the filename to download only')
|
|
16
15
|
.option('-e, --exclude [exclude]', 'specify a directory to exclude from download')
|
|
17
16
|
.option('-c, --channel_id [channelId]', 'specify the channel ID of the storefront', parseInt)
|
|
18
|
-
.option('-o, --overwrite', 'overwrite local with remote files')
|
|
19
|
-
.parse(process.argv);
|
|
17
|
+
.option('-o, --overwrite', 'overwrite local with remote files');
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const cliOptions = program.opts();
|
|
19
|
+
const cliOptions = prepareCommand(program);
|
|
24
20
|
const extraExclude = cliOptions.exclude ? [cliOptions.exclude] : [];
|
|
25
21
|
const options = {
|
|
26
22
|
exclude: ['parsed', 'manifest.json', ...extraExclude],
|
package/bin/stencil-init.js
CHANGED
|
@@ -4,19 +4,16 @@ const program = require('../lib/commander');
|
|
|
4
4
|
|
|
5
5
|
const StencilInit = require('../lib/stencil-init');
|
|
6
6
|
const { PACKAGE_INFO } = require('../constants');
|
|
7
|
-
const {
|
|
7
|
+
const { prepareCommand, printCliResultErrorAndExit } = require('../lib/cliCommon');
|
|
8
8
|
|
|
9
9
|
program
|
|
10
10
|
.version(PACKAGE_INFO.version)
|
|
11
11
|
.option('-u, --url [url]', 'Store URL')
|
|
12
12
|
.option('-t, --token [token]', 'Access Token')
|
|
13
13
|
.option('-p, --port [port]', 'Port')
|
|
14
|
-
.option('-h, --apiHost [host]', 'API Host')
|
|
15
|
-
.parse(process.argv);
|
|
14
|
+
.option('-h, --apiHost [host]', 'API Host');
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const cliOptions = program.opts();
|
|
16
|
+
const cliOptions = prepareCommand(program);
|
|
20
17
|
|
|
21
18
|
new StencilInit()
|
|
22
19
|
.run({
|
package/bin/stencil-pull.js
CHANGED
|
@@ -5,13 +5,12 @@ require('colors');
|
|
|
5
5
|
const { PACKAGE_INFO } = require('../constants');
|
|
6
6
|
const program = require('../lib/commander');
|
|
7
7
|
const stencilPull = require('../lib/stencil-pull');
|
|
8
|
-
const {
|
|
8
|
+
const { prepareCommand } = require('../lib/cliCommon');
|
|
9
9
|
const { printCliResultErrorAndExit } = require('../lib/cliCommon');
|
|
10
10
|
|
|
11
11
|
program
|
|
12
12
|
.version(PACKAGE_INFO.version)
|
|
13
13
|
.option('-s, --saved', 'get the saved configuration instead of the active one')
|
|
14
|
-
.option('-h, --host [hostname]', 'specify the api host')
|
|
15
14
|
.option(
|
|
16
15
|
'-f, --filename [filename]',
|
|
17
16
|
'specify the filename to save the config as',
|
|
@@ -21,12 +20,9 @@ program
|
|
|
21
20
|
'-c, --channel_id [channelId]',
|
|
22
21
|
'specify the channel ID of the storefront to pull configuration from',
|
|
23
22
|
parseInt,
|
|
24
|
-
)
|
|
25
|
-
.parse(process.argv);
|
|
26
|
-
|
|
27
|
-
checkNodeVersion();
|
|
23
|
+
);
|
|
28
24
|
|
|
29
|
-
const cliOptions = program
|
|
25
|
+
const cliOptions = prepareCommand(program);
|
|
30
26
|
|
|
31
27
|
const options = {
|
|
32
28
|
apiHost: cliOptions.host,
|
package/bin/stencil-push.js
CHANGED
|
@@ -4,12 +4,11 @@ require('colors');
|
|
|
4
4
|
const { PACKAGE_INFO } = require('../constants');
|
|
5
5
|
const program = require('../lib/commander');
|
|
6
6
|
const stencilPush = require('../lib/stencil-push');
|
|
7
|
-
const {
|
|
7
|
+
const { prepareCommand } = require('../lib/cliCommon');
|
|
8
8
|
const { printCliResultErrorAndExit } = require('../lib/cliCommon');
|
|
9
9
|
|
|
10
10
|
program
|
|
11
11
|
.version(PACKAGE_INFO.version)
|
|
12
|
-
.option('--host [hostname]', 'specify the api host')
|
|
13
12
|
.option('-f, --file [filename]', 'specify the filename of the bundle to upload')
|
|
14
13
|
.option('-s, --save [filename]', 'specify the filename to save the bundle as')
|
|
15
14
|
.option('-a, --activate [variationname]', 'specify the variation of the theme to activate')
|
|
@@ -18,12 +17,9 @@ program
|
|
|
18
17
|
'-c, --channel_ids <channelIds...>',
|
|
19
18
|
'specify the channel IDs of the storefront to push the theme to',
|
|
20
19
|
)
|
|
21
|
-
.option('-allc, --all_channels', 'push a theme to all available channels')
|
|
22
|
-
.parse(process.argv);
|
|
20
|
+
.option('-allc, --all_channels', 'push a theme to all available channels');
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const cliOptions = program.opts();
|
|
22
|
+
const cliOptions = prepareCommand(program);
|
|
27
23
|
const options = {
|
|
28
24
|
apiHost: cliOptions.host,
|
|
29
25
|
channelIds: cliOptions.channel_ids,
|
package/bin/stencil-start.js
CHANGED
|
@@ -4,7 +4,7 @@ require('colors');
|
|
|
4
4
|
const { PACKAGE_INFO } = require('../constants');
|
|
5
5
|
const program = require('../lib/commander');
|
|
6
6
|
const StencilStart = require('../lib/stencil-start');
|
|
7
|
-
const { printCliResultErrorAndExit } = require('../lib/cliCommon');
|
|
7
|
+
const { printCliResultErrorAndExit, prepareCommand } = require('../lib/cliCommon');
|
|
8
8
|
const BuildConfigManager = require('../lib/BuildConfigManager');
|
|
9
9
|
|
|
10
10
|
program
|
|
@@ -12,7 +12,6 @@ program
|
|
|
12
12
|
.option('-o, --open', 'Automatically open default browser')
|
|
13
13
|
.option('-v, --variation [name]', 'Set which theme variation to use while developing')
|
|
14
14
|
.option('-c, --channelId [channelId]', 'Set the channel id for the storefront')
|
|
15
|
-
.option('--host [hostname]', 'specify the api host')
|
|
16
15
|
.option(
|
|
17
16
|
'--tunnel [name]',
|
|
18
17
|
'Create a tunnel URL which points to your local server that anyone can use.',
|
|
@@ -21,11 +20,9 @@ program
|
|
|
21
20
|
'-n, --no-cache',
|
|
22
21
|
'Turns off caching for API resource data per storefront page. The cache lasts for 5 minutes before automatically refreshing.',
|
|
23
22
|
)
|
|
24
|
-
.option('-t, --timeout', 'Set a timeout for the bundle operation. Default is 20 secs', '60')
|
|
25
|
-
.parse(process.argv);
|
|
26
|
-
|
|
27
|
-
const cliOptions = program.opts();
|
|
23
|
+
.option('-t, --timeout', 'Set a timeout for the bundle operation. Default is 20 secs', '60');
|
|
28
24
|
|
|
25
|
+
const cliOptions = prepareCommand(program);
|
|
29
26
|
const options = {
|
|
30
27
|
open: cliOptions.open,
|
|
31
28
|
variation: cliOptions.variation,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class StencilCLISettings {
|
|
2
|
+
constructor() {
|
|
3
|
+
// The setting enables/disables verbose network requests logging
|
|
4
|
+
this.versboseNetworkLogging = true;
|
|
5
|
+
// Enables usage of node sass fork for testing purposes
|
|
6
|
+
this.oldNodeSassFork = false;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
setVerbose(flag) {
|
|
10
|
+
this.versboseNetworkLogging = flag;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
isVerbose() {
|
|
14
|
+
return this.versboseNetworkLogging === true;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
useOldNodeSassFork(flag) {
|
|
18
|
+
this.oldNodeSassFork = flag;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
isOldNodeSassForkEnabled() {
|
|
22
|
+
return this.oldNodeSassFork;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const settings = new StencilCLISettings();
|
|
27
|
+
|
|
28
|
+
module.exports = settings;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const fsModule = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const osModule = require('os');
|
|
4
|
+
|
|
5
|
+
const { PACKAGE_INFO, THEME_PATH } = require('../constants');
|
|
6
|
+
const ThemeConfig = require('./theme-config');
|
|
7
|
+
const StencilConfigManager = require('./StencilConfigManager');
|
|
8
|
+
|
|
9
|
+
class StencilDebug {
|
|
10
|
+
constructor({
|
|
11
|
+
fs = fsModule,
|
|
12
|
+
os = osModule,
|
|
13
|
+
logger = console,
|
|
14
|
+
themeConfig = ThemeConfig.getInstance(THEME_PATH),
|
|
15
|
+
stencilConfigManager = new StencilConfigManager(),
|
|
16
|
+
} = {}) {
|
|
17
|
+
this._fs = fs;
|
|
18
|
+
this._os = os;
|
|
19
|
+
this._logger = logger;
|
|
20
|
+
this._themeConfig = themeConfig;
|
|
21
|
+
this._stencilConfigManager = stencilConfigManager;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async run(options) {
|
|
25
|
+
const platform = this.getPlatformInfo();
|
|
26
|
+
const nodeVersion = this.getNodeJsVersion();
|
|
27
|
+
const version = this.getCliVersion();
|
|
28
|
+
const theme = await this.getThemeInfo();
|
|
29
|
+
const stencil = await this.getStencilInfo();
|
|
30
|
+
const info = {
|
|
31
|
+
platform,
|
|
32
|
+
version,
|
|
33
|
+
nodeVersion,
|
|
34
|
+
stencil,
|
|
35
|
+
theme,
|
|
36
|
+
};
|
|
37
|
+
const result = this.prepareResult(info);
|
|
38
|
+
await this.printResult(result, options);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getPlatformInfo() {
|
|
42
|
+
return {
|
|
43
|
+
type: this._os.type(),
|
|
44
|
+
version: this._os.version(),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
getNodeJsVersion() {
|
|
49
|
+
return process.version;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
getCliVersion() {
|
|
53
|
+
return PACKAGE_INFO.version;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async getThemeInfo() {
|
|
57
|
+
this.checkExecutableLocation(this._themeConfig);
|
|
58
|
+
|
|
59
|
+
const rawConfig = await this._themeConfig.getRawConfig();
|
|
60
|
+
const {
|
|
61
|
+
name,
|
|
62
|
+
version,
|
|
63
|
+
/* eslint-disable camelcase */
|
|
64
|
+
template_engine,
|
|
65
|
+
css_compiler,
|
|
66
|
+
meta: { author_name },
|
|
67
|
+
/* eslint-enable camelcase */
|
|
68
|
+
} = rawConfig;
|
|
69
|
+
return {
|
|
70
|
+
name,
|
|
71
|
+
version,
|
|
72
|
+
template_engine,
|
|
73
|
+
css_compiler,
|
|
74
|
+
author_name,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async getStencilInfo() {
|
|
79
|
+
const { apiHost, normalStoreUrl, port } = await this._stencilConfigManager.read();
|
|
80
|
+
return {
|
|
81
|
+
apiHost,
|
|
82
|
+
normalStoreUrl,
|
|
83
|
+
port,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
checkExecutableLocation(themeConfig) {
|
|
88
|
+
if (!themeConfig.configExists()) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
`${
|
|
91
|
+
'You must have a '.red + 'config.json'.cyan
|
|
92
|
+
} file in your top level theme directory.`,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
prepareResult(data) {
|
|
98
|
+
return JSON.stringify(data);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async printResult(result, options) {
|
|
102
|
+
if (options.output) {
|
|
103
|
+
const filePath = options.output.startsWith('/')
|
|
104
|
+
? options.output
|
|
105
|
+
: path.join(process.cwd(), options.output);
|
|
106
|
+
await this._fs.promises.writeFile(filePath, result);
|
|
107
|
+
} else {
|
|
108
|
+
this._logger.log(result);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = StencilDebug;
|
package/lib/bundle-validator.js
CHANGED
|
@@ -15,6 +15,7 @@ const privateThemeConfigValidationSchema = require('./schemas/privateThemeConfig
|
|
|
15
15
|
const themeConfigValidationSchema = require('./schemas/themeConfig.json');
|
|
16
16
|
const themeValidationSchema = require('./schemas/themeSchema.json');
|
|
17
17
|
const cssCompiler = require('./css/compile');
|
|
18
|
+
const stencilCLISettings = require('./StencilCLISettings');
|
|
18
19
|
|
|
19
20
|
const VALID_IMAGE_TYPES = ['.jpg', '.jpeg', '.png', '.gif'];
|
|
20
21
|
const WIDTH_COMPOSED = 600;
|
|
@@ -27,6 +28,8 @@ const MAX_SIZE_COMPOSED = 1024 * 1024 * 2; // 2MB
|
|
|
27
28
|
const MAX_SIZE_MOBILE = 1024 * 1024; // 1MB
|
|
28
29
|
const MAX_SIZE_DESKTOP = 1024 * 1024 * 5; // 5MB
|
|
29
30
|
|
|
31
|
+
/* eslint-disable no-useless-escape */
|
|
32
|
+
const STYLESHEET_REGEXP = /{{\s*stylesheet\s*([\/a-zA-Z'"\.-]+)\s*}}/i;
|
|
30
33
|
class BundleValidator {
|
|
31
34
|
/**
|
|
32
35
|
* Run some validations to ensure that the platform will accept the theme
|
|
@@ -408,24 +411,30 @@ class BundleValidator {
|
|
|
408
411
|
const assetsPath = path.join(this.themePath, 'assets');
|
|
409
412
|
const stylesPath = path.join(this.themePath, 'assets/scss');
|
|
410
413
|
const rawConfig = await this.themeConfig.getRawConfig();
|
|
411
|
-
const
|
|
412
|
-
|
|
413
|
-
let cssFiles;
|
|
414
|
-
try {
|
|
415
|
-
const files = await fs.promises.readdir(stylesPath);
|
|
416
|
-
cssFiles = files.filter((file) => {
|
|
417
|
-
return file.slice(-(compiler.length + 1)) === `.${compiler}`;
|
|
418
|
-
});
|
|
419
|
-
} catch (e) {
|
|
420
|
-
throw new Error(`Error: ${e.message}, while reading files from "${stylesPath}".`.red);
|
|
421
|
-
}
|
|
414
|
+
const cssFiles = await this.getCssFiles();
|
|
422
415
|
|
|
423
416
|
for (const file of cssFiles) {
|
|
424
417
|
try {
|
|
418
|
+
const engine = stencilCLISettings.isOldNodeSassForkEnabled()
|
|
419
|
+
? cssCompiler.FALLBACK_SASS_ENGINE_NAME
|
|
420
|
+
: cssCompiler.SASS_ENGINE_NAME;
|
|
425
421
|
/* eslint-disable-next-line no-await-in-loop */
|
|
426
|
-
await cssCompiler.compile(rawConfig, assetsPath, file);
|
|
422
|
+
await cssCompiler.compile(rawConfig, assetsPath, file, engine);
|
|
427
423
|
} catch (e) {
|
|
428
424
|
const message = this.parseStencilStylesError(e);
|
|
425
|
+
if (!stencilCLISettings.isOldNodeSassForkEnabled()) {
|
|
426
|
+
throw new Error(
|
|
427
|
+
`${message}\n`.red +
|
|
428
|
+
`\n` +
|
|
429
|
+
`---------WARNING---------\n`.red +
|
|
430
|
+
`We are currently in the process of deprecating node-sass fork https://github.com/bigcommerce-labs/node-sass\n` +
|
|
431
|
+
`Your scss files were compiled using latest node-sass version https://github.com/sass/node-sass\n` +
|
|
432
|
+
`This error might indicate that your scss file is not compatible with it.\n` +
|
|
433
|
+
`There is still an option to compile scss file old fork by using --use-old-node-sass-fork.\n` +
|
|
434
|
+
`But note, that this will lead to 500 error in production in near future.\n` +
|
|
435
|
+
`---------WARNING---------\n`.red,
|
|
436
|
+
);
|
|
437
|
+
}
|
|
429
438
|
throw new Error(
|
|
430
439
|
`${message} while compiling css files from "${stylesPath}/${file}".`.red,
|
|
431
440
|
);
|
|
@@ -433,6 +442,69 @@ class BundleValidator {
|
|
|
433
442
|
}
|
|
434
443
|
}
|
|
435
444
|
|
|
445
|
+
async getCssFiles() {
|
|
446
|
+
const templatesPath = path.join(this.themePath, 'templates');
|
|
447
|
+
const files = await recursiveReadDir(templatesPath);
|
|
448
|
+
const cssFiles = [];
|
|
449
|
+
for await (const file of files) {
|
|
450
|
+
const content = await fs.promises.readFile(file, { encoding: 'utf-8' });
|
|
451
|
+
const result = content.match(STYLESHEET_REGEXP);
|
|
452
|
+
if (result) {
|
|
453
|
+
// remove quotes
|
|
454
|
+
const fileName = result[1].slice(1, -1);
|
|
455
|
+
|
|
456
|
+
const filePath = this.tryToResolveCssFileLocation(fileName, result);
|
|
457
|
+
if (!cssFiles.includes(filePath)) {
|
|
458
|
+
// check if file exist
|
|
459
|
+
cssFiles.push(filePath);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
return cssFiles;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// returns relative path starting from root scss/css folder
|
|
468
|
+
tryToResolveCssFileLocation(fileName, result) {
|
|
469
|
+
const possibleLocations = [
|
|
470
|
+
fileName,
|
|
471
|
+
fileName.replace('/css/', '/scss/'),
|
|
472
|
+
fileName.replace('/scss/', '/css/'),
|
|
473
|
+
fileName.replace('/css/', '/scss/').replace('.css', '.scss'),
|
|
474
|
+
fileName.replace('/scss/', '/css/').replace('.scss', '.css'),
|
|
475
|
+
];
|
|
476
|
+
|
|
477
|
+
for (const location of possibleLocations) {
|
|
478
|
+
const filePath = path.join(this.themePath, location);
|
|
479
|
+
if (fs.existsSync(filePath)) {
|
|
480
|
+
if (!this.isRootCssFile(location)) {
|
|
481
|
+
return this.getCssFileWithoutRootFolder(location);
|
|
482
|
+
}
|
|
483
|
+
const fileParts = path.parse(filePath);
|
|
484
|
+
return fileParts.name;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
throw new Error(`Couldn't find file for this statement: ${result[0]}`.red);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// root folders are /assets/css /assets/scss
|
|
492
|
+
// so after split, there can be 3 or 4 elements in the array (depending if the leading slash is present)
|
|
493
|
+
isRootCssFile(location) {
|
|
494
|
+
return location.split('/').length <= 4;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
getCssFileWithoutRootFolder(location) {
|
|
498
|
+
const locationParts = location.split('/');
|
|
499
|
+
if (locationParts[0] === '') {
|
|
500
|
+
locationParts.shift();
|
|
501
|
+
}
|
|
502
|
+
locationParts.shift();
|
|
503
|
+
locationParts.shift();
|
|
504
|
+
|
|
505
|
+
return locationParts.join('/');
|
|
506
|
+
}
|
|
507
|
+
|
|
436
508
|
parseStencilStylesError(e) {
|
|
437
509
|
if (e.formatted) {
|
|
438
510
|
return `${e.formatted.replace('Error: ', '')}: `;
|
package/lib/cliCommon.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const semver = require('semver');
|
|
2
2
|
const { PACKAGE_INFO } = require('../constants');
|
|
3
|
+
const stencilCLISettings = require('./StencilCLISettings');
|
|
3
4
|
|
|
4
5
|
const messages = {
|
|
5
6
|
visitTroubleshootingPage:
|
|
@@ -8,6 +9,31 @@ const messages = {
|
|
|
8
9
|
'If this error persists, please visit https://github.com/bigcommerce/stencil-cli/issues and submit an issue.',
|
|
9
10
|
};
|
|
10
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @param {Object} object
|
|
14
|
+
|
|
15
|
+
* @returns {void}
|
|
16
|
+
*/
|
|
17
|
+
function printObject(object) {
|
|
18
|
+
for (const property of Object.keys(object)) {
|
|
19
|
+
console.log(`${property}: ${object[property]}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {Error} error
|
|
25
|
+
|
|
26
|
+
* @returns {void}
|
|
27
|
+
*/
|
|
28
|
+
function printNetworkError(config) {
|
|
29
|
+
console.log(`URL: `.yellow + config.url);
|
|
30
|
+
console.log(`Method: `.yellow + config.method.toUpperCase());
|
|
31
|
+
if (config.data) {
|
|
32
|
+
console.log(`Data: `.yellow);
|
|
33
|
+
printObject(config.data);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
11
37
|
/**
|
|
12
38
|
* @param {Error} error
|
|
13
39
|
* @param {Array<{message: string}>} [error.messages]
|
|
@@ -24,6 +50,12 @@ function printCliResultError(error) {
|
|
|
24
50
|
}
|
|
25
51
|
}
|
|
26
52
|
|
|
53
|
+
if (error && (error.config || error.response)) {
|
|
54
|
+
// In case if request didn't receive any response, response object is not available
|
|
55
|
+
const networkReq = error.config || error.response;
|
|
56
|
+
printNetworkError(networkReq);
|
|
57
|
+
}
|
|
58
|
+
|
|
27
59
|
console.log(messages.visitTroubleshootingPage);
|
|
28
60
|
|
|
29
61
|
console.log(messages.submitGithubIssue);
|
|
@@ -52,9 +84,37 @@ function checkNodeVersion() {
|
|
|
52
84
|
return satisfies;
|
|
53
85
|
}
|
|
54
86
|
|
|
87
|
+
function applyCommonOptions(program) {
|
|
88
|
+
program
|
|
89
|
+
.option('-h, --host [hostname]', 'specify the api host')
|
|
90
|
+
.option('-nov, --no-verbose', 'supress verbose info logging', false)
|
|
91
|
+
.option(
|
|
92
|
+
'--use-old-node-sass-fork',
|
|
93
|
+
'use old node sass fork for scss compilation during bundling',
|
|
94
|
+
false,
|
|
95
|
+
)
|
|
96
|
+
.parse(process.argv);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function setupCLI(options) {
|
|
100
|
+
stencilCLISettings.setVerbose(options.verbose);
|
|
101
|
+
stencilCLISettings.useOldNodeSassFork(options.useOldNodeSassFork);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function prepareCommand(program) {
|
|
105
|
+
applyCommonOptions(program);
|
|
106
|
+
checkNodeVersion();
|
|
107
|
+
|
|
108
|
+
const options = program.opts();
|
|
109
|
+
setupCLI(options);
|
|
110
|
+
|
|
111
|
+
return options;
|
|
112
|
+
}
|
|
113
|
+
|
|
55
114
|
module.exports = {
|
|
56
115
|
messages,
|
|
57
116
|
printCliResultError,
|
|
58
117
|
printCliResultErrorAndExit,
|
|
59
118
|
checkNodeVersion,
|
|
119
|
+
prepareCommand,
|
|
60
120
|
};
|
package/lib/css/compile.js
CHANGED
|
@@ -4,9 +4,10 @@ const { promisify } = require('util');
|
|
|
4
4
|
|
|
5
5
|
const cssAssembler = require('../css-assembler');
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const FALLBACK_SASS_ENGINE_NAME = 'node-sass-fork';
|
|
8
|
+
const SASS_ENGINE_NAME = 'node-sass';
|
|
8
9
|
|
|
9
|
-
const compile = async (configuration, themeAssetsPath, fileName) => {
|
|
10
|
+
const compile = async (configuration, themeAssetsPath, fileName, engineName = SASS_ENGINE_NAME) => {
|
|
10
11
|
const fileParts = path.parse(fileName);
|
|
11
12
|
const ext = configuration.css_compiler === 'css' ? configuration.css_compiler : 'scss';
|
|
12
13
|
const pathToFile = path.join(fileParts.dir, `${fileParts.name}.${ext}`);
|
|
@@ -32,11 +33,13 @@ const compile = async (configuration, themeAssetsPath, fileName) => {
|
|
|
32
33
|
},
|
|
33
34
|
};
|
|
34
35
|
const stencilStyles = new StencilStyles(console);
|
|
35
|
-
stencilStyles.activateEngine(
|
|
36
|
+
stencilStyles.activateEngine(engineName);
|
|
36
37
|
|
|
37
38
|
return stencilStyles.compileCss('scss', params);
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
module.exports = {
|
|
41
42
|
compile,
|
|
43
|
+
SASS_ENGINE_NAME,
|
|
44
|
+
FALLBACK_SASS_ENGINE_NAME,
|
|
42
45
|
};
|
|
@@ -7,6 +7,7 @@ const fsModule = require('fs');
|
|
|
7
7
|
const axios = require('axios');
|
|
8
8
|
|
|
9
9
|
const { PACKAGE_INFO } = require('../../constants');
|
|
10
|
+
const stencilCLISettings = require('../StencilCLISettings');
|
|
10
11
|
|
|
11
12
|
const defaultHttpsAgent = new https.Agent({ rejectUnauthorized: false });
|
|
12
13
|
|
|
@@ -16,11 +17,13 @@ class NetworkUtils {
|
|
|
16
17
|
httpsAgent = defaultHttpsAgent,
|
|
17
18
|
reqLibrary = axios,
|
|
18
19
|
packageInfo = PACKAGE_INFO,
|
|
20
|
+
logger = console,
|
|
19
21
|
} = {}) {
|
|
20
22
|
this._fs = fs;
|
|
21
23
|
this._httpsAgent = httpsAgent;
|
|
22
24
|
this._reqLibrary = reqLibrary;
|
|
23
25
|
this._packageInfo = packageInfo;
|
|
26
|
+
this._logger = logger;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
/** Used to send request to our (Bigcommerce) servers only.
|
|
@@ -50,6 +53,10 @@ class NetworkUtils {
|
|
|
50
53
|
reqConfig.headers['x-auth-token'] = accessToken;
|
|
51
54
|
}
|
|
52
55
|
|
|
56
|
+
if (stencilCLISettings.isVerbose()) {
|
|
57
|
+
this.log(reqConfig);
|
|
58
|
+
}
|
|
59
|
+
|
|
53
60
|
return this._reqLibrary(reqConfig);
|
|
54
61
|
}
|
|
55
62
|
|
|
@@ -71,6 +78,11 @@ class NetworkUtils {
|
|
|
71
78
|
.on('error', reject);
|
|
72
79
|
});
|
|
73
80
|
}
|
|
81
|
+
|
|
82
|
+
log(config) {
|
|
83
|
+
const method = config.method || 'GET';
|
|
84
|
+
this._logger.info(`Upcoming request ${method.green}: ${config.url.green}`);
|
|
85
|
+
}
|
|
74
86
|
}
|
|
75
87
|
|
|
76
88
|
module.exports = NetworkUtils;
|