@bigcommerce/stencil-cli 8.3.0 → 8.4.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 +1 -1
- package/bin/stencil-bundle.js +7 -18
- package/bin/stencil-debug.js +5 -9
- package/bin/stencil-download.js +7 -19
- package/bin/stencil-init.js +4 -8
- package/bin/stencil-pull.js +5 -11
- package/bin/stencil-push.js +5 -8
- package/bin/stencil-release.js +5 -10
- package/bin/stencil-scss-autofix.js +6 -11
- package/bin/stencil-start.js +6 -9
- package/bin/stencil.js +2 -3
- package/constants.js +9 -9
- package/lib/BuildConfigManager.js +25 -23
- package/lib/Cycles.js +3 -12
- package/lib/ScssValidator.js +5 -9
- package/lib/StencilCLISettings.js +1 -3
- package/lib/StencilConfigManager.js +6 -22
- package/lib/StencilDebug.js +7 -10
- package/lib/archiveManager.js +7 -23
- package/lib/bundle-validator.js +28 -64
- package/lib/cliCommon.js +11 -21
- package/lib/commander.js +2 -3
- package/lib/content-api-client.js +5 -13
- package/lib/css/compile.js +3 -6
- package/lib/graphql/query.js +5 -8
- package/lib/lang/validator.js +5 -11
- package/lib/lang-assembler.js +4 -10
- package/lib/lang-helper.js +3 -6
- package/lib/nodeSass/AutoFixer.js +10 -19
- package/lib/nodeSass/BaseFixer.js +5 -7
- package/lib/nodeSass/BaseRulesFixer.js +3 -8
- package/lib/nodeSass/CommaRemovalFixer.js +3 -8
- package/lib/nodeSass/ConditionalImportFixer.js +3 -9
- package/lib/nodeSass/UndefinedVariableFixer.js +3 -6
- package/lib/parse-json.js +10 -9
- package/lib/regions.js +3 -23
- package/lib/release/questions.js +3 -13
- package/lib/release/release.js +16 -55
- package/lib/spinner.js +1 -2
- package/lib/stencil-bundle.js +15 -75
- package/lib/stencil-download.js +5 -6
- package/lib/stencil-download.utils.js +5 -18
- package/lib/stencil-init.js +8 -24
- package/lib/stencil-pull.js +4 -5
- package/lib/stencil-pull.utils.js +5 -28
- package/lib/stencil-push.js +3 -4
- package/lib/stencil-push.utils.js +12 -102
- package/lib/stencil-start.js +19 -48
- package/lib/store-settings-api-client.js +4 -7
- package/lib/template-assembler.js +6 -45
- package/lib/theme-api-client.js +7 -30
- package/lib/theme-config.js +16 -59
- package/lib/utils/NetworkUtils.js +6 -16
- package/lib/utils/asyncUtils.js +2 -3
- package/lib/utils/frontmatter.js +4 -5
- package/lib/utils/fsUtils.js +6 -10
- package/lib/validator/schema-translations.js +5 -7
- package/package.json +11 -8
- package/server/config.js +3 -7
- package/server/index.js +29 -29
- package/server/lib/page-type-util.js +2 -5
- package/server/lib/show-logo.js +3 -3
- package/server/lib/utils.js +6 -11
- package/server/manifest.js +7 -11
- package/server/plugins/renderer/renderer.module.js +38 -100
- package/server/plugins/renderer/responses/index.js +7 -4
- package/server/plugins/renderer/responses/pencil-response.js +4 -32
- package/server/plugins/renderer/responses/raw-response.js +6 -14
- package/server/plugins/renderer/responses/redirect-response.js +1 -4
- package/server/plugins/router/router.module.js +9 -14
- package/server/plugins/theme-assets/theme-assets.module.js +15 -27
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { each } from 'lodash-es';
|
|
2
|
+
import Paper from '@bigcommerce/stencil-paper';
|
|
4
3
|
/**
|
|
5
4
|
* Escapes html entities
|
|
6
5
|
*
|
|
@@ -13,17 +12,14 @@ const escapeHtml = (html) => {
|
|
|
13
12
|
'>': '>',
|
|
14
13
|
'"': '"',
|
|
15
14
|
};
|
|
16
|
-
|
|
17
15
|
return html.replace(/[&<>"]/g, (tag) => charsToReplace[tag] || tag);
|
|
18
16
|
};
|
|
19
|
-
|
|
20
17
|
/**
|
|
21
18
|
* Scape special characters for regular expression
|
|
22
19
|
*
|
|
23
20
|
* @param {string} string
|
|
24
21
|
*/
|
|
25
22
|
const escapeRegex = (string) => string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
26
|
-
|
|
27
23
|
/**
|
|
28
24
|
* Returns template path
|
|
29
25
|
*
|
|
@@ -33,24 +29,18 @@ const escapeRegex = (string) => string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
|
33
29
|
*/
|
|
34
30
|
const getTemplatePath = (request, data) => {
|
|
35
31
|
let paths = data.template_file;
|
|
36
|
-
|
|
37
32
|
if (request.headers['stencil-options']) {
|
|
38
33
|
const options = JSON.parse(request.headers['stencil-options']);
|
|
39
|
-
|
|
40
34
|
if (options.render_with && typeof options.render_with === 'string') {
|
|
41
35
|
const componentsToRender = options.render_with.split(',');
|
|
42
|
-
|
|
43
36
|
paths = componentsToRender.map((component) => `components/${component}`);
|
|
44
|
-
|
|
45
37
|
if (paths.length === 1) {
|
|
46
38
|
[paths] = paths;
|
|
47
39
|
}
|
|
48
40
|
}
|
|
49
41
|
}
|
|
50
|
-
|
|
51
42
|
return paths;
|
|
52
43
|
};
|
|
53
|
-
|
|
54
44
|
/**
|
|
55
45
|
* Returns boolean if this handlebars version is supported
|
|
56
46
|
*
|
|
@@ -58,7 +48,6 @@ const getTemplatePath = (request, data) => {
|
|
|
58
48
|
*/
|
|
59
49
|
const isSupportedHandlebarsVersion = (version) =>
|
|
60
50
|
['handlebars-v3', 'handlebars-v4'].includes(version);
|
|
61
|
-
|
|
62
51
|
/**
|
|
63
52
|
* Node.js projects are using variables in format: handlebars-v3, handlebars-v4;
|
|
64
53
|
* Storefront and db are using format: handlebars_v3, handlebars_v4;
|
|
@@ -67,7 +56,6 @@ const isSupportedHandlebarsVersion = (version) =>
|
|
|
67
56
|
* @param {string} version
|
|
68
57
|
*/
|
|
69
58
|
const compatibilizeTemplateEngine = (version) => version.replace('_', '-');
|
|
70
|
-
|
|
71
59
|
/**
|
|
72
60
|
* Output post-processing
|
|
73
61
|
*
|
|
@@ -76,25 +64,20 @@ const compatibilizeTemplateEngine = (version) => version.replace('_', '-');
|
|
|
76
64
|
*/
|
|
77
65
|
const makeDecorator = (request, context) => (content) => {
|
|
78
66
|
let updatedContent = content;
|
|
79
|
-
|
|
80
67
|
if (context.settings) {
|
|
81
68
|
const baseUrlregex = new RegExp(escapeRegex(context.settings.base_url), 'g');
|
|
82
69
|
updatedContent = content.replace(baseUrlregex, '');
|
|
83
|
-
|
|
84
70
|
const secureBaseUrlRegex = new RegExp(escapeRegex(context.settings.secure_base_url), 'g');
|
|
85
71
|
updatedContent = content.replace(secureBaseUrlRegex, '');
|
|
86
72
|
}
|
|
87
|
-
|
|
88
73
|
if (request.query.debug === 'bar') {
|
|
89
74
|
const contextStr = escapeHtml(JSON.stringify(context, null, 2));
|
|
90
75
|
const debugBar = `<pre style="background-color:#EEE; word-wrap:break-word;"> ${contextStr} </pre>`;
|
|
91
76
|
const bodyRegex = new RegExp('</body>');
|
|
92
77
|
updatedContent = content.replace(bodyRegex, `${debugBar}\n</body>`);
|
|
93
78
|
}
|
|
94
|
-
|
|
95
79
|
return updatedContent;
|
|
96
80
|
};
|
|
97
|
-
|
|
98
81
|
class PencilResponse {
|
|
99
82
|
/**
|
|
100
83
|
* @param {Object} data
|
|
@@ -120,13 +103,11 @@ class PencilResponse {
|
|
|
120
103
|
const templateEngine = compatibilizeTemplateEngine(
|
|
121
104
|
this.data.context.template_engine || 'handlebars-v3',
|
|
122
105
|
);
|
|
123
|
-
|
|
124
106
|
if (!isSupportedHandlebarsVersion(templateEngine)) {
|
|
125
107
|
throw new Error(
|
|
126
108
|
'Provided Handlebars version is not supported! Please use:handlebars-v3, handlebars-v4',
|
|
127
109
|
);
|
|
128
110
|
}
|
|
129
|
-
|
|
130
111
|
const paper = new Paper(
|
|
131
112
|
this.data.context.settings,
|
|
132
113
|
this.data.context.theme_settings,
|
|
@@ -136,31 +117,23 @@ class PencilResponse {
|
|
|
136
117
|
// Set the environment to dev
|
|
137
118
|
this.data.context.in_development = true;
|
|
138
119
|
this.data.context.in_production = false;
|
|
139
|
-
|
|
140
120
|
paper.addDecorator(makeDecorator(request, this.data.context));
|
|
141
121
|
paper.setContent(this.data.renderedRegions);
|
|
142
|
-
|
|
143
122
|
// Plugins have the opportunity to add/modify the response by using decorators
|
|
144
|
-
|
|
123
|
+
each(request.app.decorators, (decorator) => {
|
|
145
124
|
paper.addDecorator(decorator);
|
|
146
125
|
});
|
|
147
|
-
|
|
148
126
|
const templatePath = getTemplatePath(request, this.data);
|
|
149
|
-
|
|
150
127
|
if (request.query.debug === 'context') {
|
|
151
128
|
return this.data.context;
|
|
152
129
|
}
|
|
153
|
-
|
|
154
130
|
try {
|
|
155
131
|
await paper.loadTheme(templatePath, this.data.acceptLanguage);
|
|
156
132
|
const output = await paper.renderTheme(templatePath, this.data);
|
|
157
|
-
|
|
158
133
|
const response = h.response(output).code(this.data.statusCode);
|
|
159
|
-
|
|
160
134
|
if (this.data.headers['set-cookie']) {
|
|
161
135
|
response.header('set-cookie', this.data.headers['set-cookie']);
|
|
162
136
|
}
|
|
163
|
-
|
|
164
137
|
return response;
|
|
165
138
|
} catch (err) {
|
|
166
139
|
console.error(err.message.red);
|
|
@@ -168,5 +141,4 @@ class PencilResponse {
|
|
|
168
141
|
}
|
|
169
142
|
}
|
|
170
143
|
}
|
|
171
|
-
|
|
172
|
-
module.exports = PencilResponse;
|
|
144
|
+
export default PencilResponse;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import * as cheerio from 'cheerio';
|
|
2
|
+
import { int2uuid } from '../../../lib/utils.js';
|
|
3
3
|
|
|
4
4
|
const internals = {
|
|
5
|
-
stubActiveVersion:
|
|
6
|
-
stubActiveConfig:
|
|
5
|
+
stubActiveVersion: int2uuid(1),
|
|
6
|
+
stubActiveConfig: int2uuid(1),
|
|
7
7
|
};
|
|
8
|
-
|
|
9
8
|
class RawResponse {
|
|
10
9
|
/**
|
|
11
10
|
* @param {buffer} data
|
|
@@ -21,15 +20,13 @@ class RawResponse {
|
|
|
21
20
|
|
|
22
21
|
respond(request, h) {
|
|
23
22
|
let payload = this.data;
|
|
24
|
-
internals.stubActiveConfig =
|
|
25
|
-
|
|
23
|
+
internals.stubActiveConfig = int2uuid(request.app.themeConfig.variationIndex + 1);
|
|
26
24
|
if (
|
|
27
25
|
request.path.startsWith('/checkout.php') ||
|
|
28
26
|
request.path.startsWith('/finishorder.php')
|
|
29
27
|
) {
|
|
30
28
|
payload = this._appendCss(payload.toString('utf8'));
|
|
31
29
|
}
|
|
32
|
-
|
|
33
30
|
// To be removed when we go to Phase 3
|
|
34
31
|
if (request.path.startsWith('/checkout')) {
|
|
35
32
|
payload = payload
|
|
@@ -39,9 +36,7 @@ class RawResponse {
|
|
|
39
36
|
`/stencil/${internals.stubActiveVersion}/${internals.stubActiveConfig}/css/optimized-checkout.css`,
|
|
40
37
|
);
|
|
41
38
|
}
|
|
42
|
-
|
|
43
39
|
const response = h.response(payload).code(this.statusCode);
|
|
44
|
-
|
|
45
40
|
for (const [name, values] of Object.entries(this.headers)) {
|
|
46
41
|
switch (name) {
|
|
47
42
|
case 'transfer-encoding':
|
|
@@ -56,7 +51,6 @@ class RawResponse {
|
|
|
56
51
|
response.header(name, values.toString());
|
|
57
52
|
}
|
|
58
53
|
}
|
|
59
|
-
|
|
60
54
|
return response;
|
|
61
55
|
}
|
|
62
56
|
|
|
@@ -69,10 +63,8 @@ class RawResponse {
|
|
|
69
63
|
_appendCss(payload) {
|
|
70
64
|
const dom = cheerio.load(payload);
|
|
71
65
|
const url = `/stencil/${internals.stubActiveVersion}/${internals.stubActiveConfig}/css/checkout.css`;
|
|
72
|
-
|
|
73
66
|
dom('head').append(`<link href="${url}" type="text/css" rel="stylesheet">`);
|
|
74
67
|
return dom.html();
|
|
75
68
|
}
|
|
76
69
|
}
|
|
77
|
-
|
|
78
|
-
module.exports = RawResponse;
|
|
70
|
+
export default RawResponse;
|
|
@@ -12,7 +12,6 @@ class RedirectResponse {
|
|
|
12
12
|
|
|
13
13
|
respond(request, h) {
|
|
14
14
|
const response = h.redirect(this.location).code(this.statusCode);
|
|
15
|
-
|
|
16
15
|
for (const [name, values] of Object.entries(this.headers)) {
|
|
17
16
|
switch (name) {
|
|
18
17
|
case 'transfer-encoding':
|
|
@@ -34,9 +33,7 @@ class RedirectResponse {
|
|
|
34
33
|
response.header(name, values.toString());
|
|
35
34
|
}
|
|
36
35
|
}
|
|
37
|
-
|
|
38
36
|
return response;
|
|
39
37
|
}
|
|
40
38
|
}
|
|
41
|
-
|
|
42
|
-
module.exports = RedirectResponse;
|
|
39
|
+
export default RedirectResponse;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { defaultsDeep } from 'lodash-es';
|
|
2
|
+
import ThemeConfig from '../../../lib/theme-config.js';
|
|
3
3
|
|
|
4
4
|
const internals = {
|
|
5
5
|
options: {
|
|
@@ -19,7 +19,6 @@ const internals = {
|
|
|
19
19
|
graphQL: '/graphql',
|
|
20
20
|
},
|
|
21
21
|
};
|
|
22
|
-
|
|
23
22
|
function mapUri(req) {
|
|
24
23
|
const host = `https://${internals.options.storeUrl.replace(/http[s]?:\/\//, '')}`;
|
|
25
24
|
const urlParams = req.url.search || '';
|
|
@@ -28,28 +27,22 @@ function mapUri(req) {
|
|
|
28
27
|
'stencil-cli': internals.options.stencilCliVersion,
|
|
29
28
|
'x-auth-token': internals.options.accessToken,
|
|
30
29
|
};
|
|
31
|
-
|
|
32
30
|
return { uri, headers };
|
|
33
31
|
}
|
|
34
|
-
|
|
35
32
|
function register(server, options) {
|
|
36
|
-
internals.options =
|
|
37
|
-
|
|
33
|
+
internals.options = defaultsDeep(options, internals.options);
|
|
38
34
|
server.ext('onRequest', (request, h) => {
|
|
39
35
|
request.app.storeUrl = internals.options.storeUrl;
|
|
40
36
|
request.app.normalStoreUrl = internals.options.normalStoreUrl;
|
|
41
37
|
request.app.apiKey = internals.options.apiKey;
|
|
42
38
|
request.app.themeConfig = ThemeConfig.getInstance();
|
|
43
|
-
|
|
44
39
|
return h.continue;
|
|
45
40
|
});
|
|
46
|
-
|
|
47
41
|
server.dependency(
|
|
48
42
|
['@hapi/inert', '@hapi/h2o2', 'Renderer', 'ThemeAssets'],
|
|
49
43
|
internals.registerRoutes,
|
|
50
44
|
);
|
|
51
45
|
}
|
|
52
|
-
|
|
53
46
|
internals.registerRoutes = (server) => {
|
|
54
47
|
server.route([
|
|
55
48
|
{
|
|
@@ -188,9 +181,11 @@ internals.registerRoutes = (server) => {
|
|
|
188
181
|
},
|
|
189
182
|
]);
|
|
190
183
|
};
|
|
191
|
-
|
|
192
|
-
|
|
184
|
+
export const name = 'Router';
|
|
185
|
+
export const version = '0.0.1';
|
|
186
|
+
export { register };
|
|
187
|
+
export default {
|
|
193
188
|
register,
|
|
194
|
-
name
|
|
195
|
-
version
|
|
189
|
+
name,
|
|
190
|
+
version,
|
|
196
191
|
};
|
|
@@ -1,42 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { defaultsDeep } from 'lodash-es';
|
|
2
|
+
import * as Boom from '@hapi/boom';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { uuidRegExp, uuid2int } from '../../lib/utils.js';
|
|
5
|
+
import cssCompiler from '../../../lib/css/compile.js';
|
|
6
6
|
|
|
7
7
|
const internals = {
|
|
8
8
|
options: {},
|
|
9
9
|
};
|
|
10
|
-
|
|
11
10
|
function register(server, options) {
|
|
12
|
-
internals.options =
|
|
13
|
-
|
|
11
|
+
internals.options = defaultsDeep(options, internals.options);
|
|
14
12
|
server.expose('cssHandler', internals.cssHandler);
|
|
15
13
|
server.expose('assetHandler', internals.assetHandler);
|
|
16
14
|
}
|
|
17
|
-
|
|
18
15
|
/**
|
|
19
16
|
* Get the variation index from the "ConfigId" in the css filename
|
|
20
17
|
* @param {string} fileName
|
|
21
18
|
* @returns {number}
|
|
22
19
|
*/
|
|
23
20
|
internals.getVariationIndex = (fileName) => {
|
|
24
|
-
const match = fileName.match(new RegExp(`.+-(${
|
|
25
|
-
|
|
26
|
-
return match ? utils.uuid2int(match[1]) - 1 : 0;
|
|
21
|
+
const match = fileName.match(new RegExp(`.+-(${uuidRegExp})$`));
|
|
22
|
+
return match ? uuid2int(match[1]) - 1 : 0;
|
|
27
23
|
};
|
|
28
|
-
|
|
29
24
|
/**
|
|
30
25
|
* Get the original css file name
|
|
31
26
|
* @param {string} fileName
|
|
32
27
|
* @returns {string}
|
|
33
28
|
*/
|
|
34
29
|
internals.getOriginalFileName = (fileName) => {
|
|
35
|
-
const match = fileName.match(new RegExp(`(.+)-${
|
|
36
|
-
|
|
30
|
+
const match = fileName.match(new RegExp(`(.+)-${uuidRegExp}$`));
|
|
37
31
|
return match ? match[1] : fileName;
|
|
38
32
|
};
|
|
39
|
-
|
|
40
33
|
/**
|
|
41
34
|
* CSS Compiler Handler. This utilises the CSS Assembler to gather all of the CSS files and then the
|
|
42
35
|
* StencilStyles plugin to compile them all.
|
|
@@ -46,19 +39,15 @@ internals.getOriginalFileName = (fileName) => {
|
|
|
46
39
|
internals.cssHandler = async (request, h) => {
|
|
47
40
|
const variationIndex = internals.getVariationIndex(request.params.fileName);
|
|
48
41
|
const variationExists = await request.app.themeConfig.variationExists(variationIndex);
|
|
49
|
-
|
|
50
42
|
if (!variationExists) {
|
|
51
43
|
throw Boom.notFound(`Variation ${variationIndex + 1} does not exist.`);
|
|
52
44
|
}
|
|
53
|
-
|
|
54
45
|
// Set the variation to get the right theme configuration
|
|
55
46
|
request.app.themeConfig.setVariation(variationIndex);
|
|
56
|
-
|
|
57
47
|
// Get the theme configuration
|
|
58
48
|
const configuration = await request.app.themeConfig.getConfig();
|
|
59
49
|
const fileName = internals.getOriginalFileName(request.params.fileName);
|
|
60
50
|
const themeAssetsPath = internals.getThemeAssetsPath();
|
|
61
|
-
|
|
62
51
|
try {
|
|
63
52
|
const css = await cssCompiler.compile(configuration, themeAssetsPath, fileName);
|
|
64
53
|
return h.response(css).type('text/css');
|
|
@@ -67,7 +56,6 @@ internals.cssHandler = async (request, h) => {
|
|
|
67
56
|
throw Boom.badData(err);
|
|
68
57
|
}
|
|
69
58
|
};
|
|
70
|
-
|
|
71
59
|
/**
|
|
72
60
|
* Assets handler
|
|
73
61
|
*
|
|
@@ -76,16 +64,16 @@ internals.cssHandler = async (request, h) => {
|
|
|
76
64
|
*/
|
|
77
65
|
internals.assetHandler = (request, h) => {
|
|
78
66
|
const filePath = path.join(internals.getThemeAssetsPath(), request.params.fileName);
|
|
79
|
-
|
|
80
67
|
return h.file(filePath);
|
|
81
68
|
};
|
|
82
|
-
|
|
83
69
|
internals.getThemeAssetsPath = () => {
|
|
84
70
|
return path.join(internals.options.themePath, 'assets');
|
|
85
71
|
};
|
|
86
|
-
|
|
87
|
-
|
|
72
|
+
export const name = 'ThemeAssets';
|
|
73
|
+
export const version = '0.0.1';
|
|
74
|
+
export { register };
|
|
75
|
+
export default {
|
|
88
76
|
register,
|
|
89
|
-
name
|
|
90
|
-
version
|
|
77
|
+
name,
|
|
78
|
+
version,
|
|
91
79
|
};
|