@bigcommerce/stencil-cli 3.8.3 → 3.9.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 +18 -0
- package/README.md +3 -1
- package/bin/stencil-init.js +2 -0
- package/bin/stencil-push.js +5 -4
- package/constants.js +0 -6
- package/lib/stencil-init.js +20 -34
- package/lib/stencil-push.js +1 -1
- package/lib/stencil-push.utils.js +43 -5
- package/lib/theme-api-client.js +19 -16
- package/lib/utils/frontmatter.js +1 -1
- package/package-lock.json +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
### 3.9.1 (2022-01-25)
|
|
2
|
+
|
|
3
|
+
- fix: strf-9612 Fix stencil pull when there is 1 channel ([859](https://github.com/bigcommerce/stencil-cli/pull/859))
|
|
4
|
+
|
|
5
|
+
### 3.9.0 (2022-01-21)
|
|
6
|
+
|
|
7
|
+
- fix: return channel id as an iterable when a store only has a single storefront ([849](https://github.com/bigcommerce/stencil-cli/pull/849))
|
|
8
|
+
- feat: warn npm users if npm is above 7 version ([846](https://github.com/bigcommerce/stencil-cli/pull/846))
|
|
9
|
+
|
|
10
|
+
### 3.8.5 (2022-01-18)
|
|
11
|
+
|
|
12
|
+
- fix(storefront): strf-9594 loosed frontmatter refex ([841](https://github.com/bigcommerce/stencil-cli/pull/841))
|
|
13
|
+
|
|
14
|
+
### 3.8.4 (2022-01-13)
|
|
15
|
+
|
|
16
|
+
- fix: `stencil init` command including `apiHost` option is now recognized ([830](https://github.com/bigcommerce/stencil-cli/pull/830))
|
|
17
|
+
- feat: `stencil push` command allows to push a theme to multiple channels ([825](https://github.com/bigcommerce/stencil-cli/pull/825))
|
|
18
|
+
|
|
1
19
|
### 3.8.3 (2022-01-12)
|
|
2
20
|
|
|
3
21
|
- fix: add activate sass engine name logic ([837](https://github.com/bigcommerce/stencil-cli/pull/837))
|
package/README.md
CHANGED
|
@@ -56,7 +56,9 @@ This is useful for tracking your changes in your Theme, and is the tool we use t
|
|
|
56
56
|
|
|
57
57
|
Run `stencil push` to bundle the local theme and upload it to your store, so it will be available in My Themes.
|
|
58
58
|
To push the theme and also activate it, use `stencil push -a`. To automatically delete the oldest theme if you are at
|
|
59
|
-
your theme limit, use `stencil push -d`. These can be used together, as `stencil push -a -d`.
|
|
59
|
+
your theme limit, use `stencil push -d`. These can be used together, as `stencil push -a -d`. You can apply the theme to
|
|
60
|
+
multiple storefronts, just specify ids of desired storefronts/channels after `-c` option `stencil push -a -c 123 456 789`.
|
|
61
|
+
If you want to apply theme to all available storefronts, just use `-allc` option: `stencil push -a -allc`.
|
|
60
62
|
|
|
61
63
|
Run `stencil pull` to sync changes to your theme configuration from your live store. For example, if Page Builder has
|
|
62
64
|
been used to change certain theme settings, this will update those settings in config.json in your theme files so you
|
package/bin/stencil-init.js
CHANGED
|
@@ -11,6 +11,7 @@ program
|
|
|
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')
|
|
14
15
|
.parse(process.argv);
|
|
15
16
|
|
|
16
17
|
checkNodeVersion();
|
|
@@ -22,5 +23,6 @@ new StencilInit()
|
|
|
22
23
|
normalStoreUrl: cliOptions.url,
|
|
23
24
|
accessToken: cliOptions.token,
|
|
24
25
|
port: cliOptions.port,
|
|
26
|
+
apiHost: cliOptions.apiHost,
|
|
25
27
|
})
|
|
26
28
|
.catch(printCliResultErrorAndExit);
|
package/bin/stencil-push.js
CHANGED
|
@@ -15,10 +15,10 @@ program
|
|
|
15
15
|
.option('-a, --activate [variationname]', 'specify the variation of the theme to activate')
|
|
16
16
|
.option('-d, --delete', 'delete oldest private theme if upload limit reached')
|
|
17
17
|
.option(
|
|
18
|
-
'-c, --
|
|
19
|
-
'specify the channel
|
|
20
|
-
parseInt,
|
|
18
|
+
'-c, --channel_ids <channelIds...>',
|
|
19
|
+
'specify the channel IDs of the storefront to push the theme to',
|
|
21
20
|
)
|
|
21
|
+
.option('-allc, --all_channels', 'push a theme to all available channels')
|
|
22
22
|
.parse(process.argv);
|
|
23
23
|
|
|
24
24
|
checkNodeVersion();
|
|
@@ -26,11 +26,12 @@ checkNodeVersion();
|
|
|
26
26
|
const cliOptions = program.opts();
|
|
27
27
|
const options = {
|
|
28
28
|
apiHost: cliOptions.host,
|
|
29
|
-
|
|
29
|
+
channelIds: cliOptions.channel_ids,
|
|
30
30
|
bundleZipPath: cliOptions.file,
|
|
31
31
|
activate: cliOptions.activate,
|
|
32
32
|
saveBundleName: cliOptions.save,
|
|
33
33
|
deleteOldest: cliOptions.delete,
|
|
34
|
+
allChannels: cliOptions.all_channels,
|
|
34
35
|
};
|
|
35
36
|
stencilPush(options, (err, result) => {
|
|
36
37
|
if (err) {
|
package/constants.js
CHANGED
|
@@ -15,17 +15,11 @@ const DEFAULT_CUSTOM_LAYOUTS_CONFIG = {
|
|
|
15
15
|
|
|
16
16
|
/// ///////////////////////////////////////// Other //////////////////////////////////////// ///
|
|
17
17
|
|
|
18
|
-
const DEV_API_HOST = 'https://api.service.bcdev';
|
|
19
|
-
const INTG_API_HOST = 'https://api.integration.zone';
|
|
20
|
-
const STG_API_HOST = 'https://api.staging.zone';
|
|
21
18
|
const API_HOST = 'https://api.bigcommerce.com';
|
|
22
19
|
|
|
23
20
|
module.exports = {
|
|
24
21
|
PACKAGE_INFO,
|
|
25
22
|
THEME_PATH,
|
|
26
23
|
DEFAULT_CUSTOM_LAYOUTS_CONFIG,
|
|
27
|
-
DEV_API_HOST,
|
|
28
|
-
INTG_API_HOST,
|
|
29
|
-
STG_API_HOST,
|
|
30
24
|
API_HOST,
|
|
31
25
|
};
|
package/lib/stencil-init.js
CHANGED
|
@@ -4,13 +4,7 @@ const inquirerModule = require('inquirer');
|
|
|
4
4
|
|
|
5
5
|
const serverConfigModule = require('../server/config');
|
|
6
6
|
const StencilConfigManager = require('./StencilConfigManager');
|
|
7
|
-
const {
|
|
8
|
-
DEFAULT_CUSTOM_LAYOUTS_CONFIG,
|
|
9
|
-
API_HOST,
|
|
10
|
-
INTG_API_HOST,
|
|
11
|
-
STG_API_HOST,
|
|
12
|
-
DEV_API_HOST,
|
|
13
|
-
} = require('../constants');
|
|
7
|
+
const { DEFAULT_CUSTOM_LAYOUTS_CONFIG, API_HOST } = require('../constants');
|
|
14
8
|
|
|
15
9
|
class StencilInit {
|
|
16
10
|
/**
|
|
@@ -71,20 +65,21 @@ class StencilInit {
|
|
|
71
65
|
}
|
|
72
66
|
|
|
73
67
|
/**
|
|
74
|
-
* @param {{port: (number), normalStoreUrl: (string), accessToken: (string)}} stencilConfig
|
|
75
|
-
* @returns {{port: (number), normalStoreUrl: (string), accessToken: (string)}}
|
|
68
|
+
* @param {{port: (number), normalStoreUrl: (string), accessToken: (string), apiHost: (string)}} stencilConfig
|
|
69
|
+
* @returns {{port: (number), normalStoreUrl: (string), accessToken: (string), apiHost: (string)}}
|
|
76
70
|
*/
|
|
77
71
|
getDefaultAnswers(stencilConfig) {
|
|
78
72
|
return {
|
|
79
73
|
normalStoreUrl: stencilConfig.normalStoreUrl,
|
|
80
74
|
accessToken: stencilConfig.accessToken,
|
|
81
75
|
port: stencilConfig.port || this._serverConfig.get('/server/port'),
|
|
76
|
+
apiHost: API_HOST,
|
|
82
77
|
};
|
|
83
78
|
}
|
|
84
79
|
|
|
85
80
|
/**
|
|
86
|
-
* @param {{port: (number), normalStoreUrl: (string), accessToken: (string)}} defaultAnswers
|
|
87
|
-
* @param {{port: (number), normalStoreUrl: (string), accessToken: (string)}} cliOptions
|
|
81
|
+
* @param {{port: (number), normalStoreUrl: (string), accessToken: (string), apiHost: (string)}} defaultAnswers
|
|
82
|
+
* @param {{port: (number), normalStoreUrl: (string), accessToken: (string), apiHost: (string)}} cliOptions
|
|
88
83
|
* @returns {{object[]}}
|
|
89
84
|
*/
|
|
90
85
|
getQuestions(defaultAnswers, cliOptions) {
|
|
@@ -110,6 +105,15 @@ class StencilInit {
|
|
|
110
105
|
});
|
|
111
106
|
}
|
|
112
107
|
|
|
108
|
+
if (!cliOptions.apiHost) {
|
|
109
|
+
prompts.push({
|
|
110
|
+
type: 'input',
|
|
111
|
+
name: 'apiHost',
|
|
112
|
+
message: 'What API Host would you like to use?',
|
|
113
|
+
default: defaultAnswers.apiHost,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
113
117
|
if (!cliOptions.port) {
|
|
114
118
|
prompts.push({
|
|
115
119
|
type: 'input',
|
|
@@ -139,27 +143,12 @@ class StencilInit {
|
|
|
139
143
|
return questions.length ? this._inquirer.prompt(questions) : {};
|
|
140
144
|
}
|
|
141
145
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
if (storeUrl !== undefined) {
|
|
145
|
-
if (storeUrl.includes('service.bcdev')) {
|
|
146
|
-
host = DEV_API_HOST;
|
|
147
|
-
}
|
|
148
|
-
if (storeUrl.includes('my-integration.zone')) {
|
|
149
|
-
host = INTG_API_HOST;
|
|
150
|
-
}
|
|
151
|
-
if (storeUrl.includes('my-staging.zone')) {
|
|
152
|
-
host = STG_API_HOST;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (host === null) {
|
|
157
|
-
host = API_HOST;
|
|
158
|
-
}
|
|
146
|
+
updateApiHost(stencilConfig, cliOptions) {
|
|
147
|
+
const host = cliOptions.apiHost || API_HOST;
|
|
159
148
|
|
|
160
149
|
console.log('Set API host to: ' + host);
|
|
161
150
|
|
|
162
|
-
return host;
|
|
151
|
+
return { ...stencilConfig, apiHost: host };
|
|
163
152
|
}
|
|
164
153
|
|
|
165
154
|
/**
|
|
@@ -169,13 +158,10 @@ class StencilInit {
|
|
|
169
158
|
* @returns {object}
|
|
170
159
|
*/
|
|
171
160
|
applyAnswers(stencilConfig, answers, cliOptions) {
|
|
172
|
-
const
|
|
173
|
-
answers.normalStoreUrl || cliOptions.normalStoreUrl || stencilConfig.normalStoreUrl;
|
|
174
|
-
|
|
161
|
+
const config = this.updateApiHost(stencilConfig, cliOptions);
|
|
175
162
|
return {
|
|
176
163
|
customLayouts: DEFAULT_CUSTOM_LAYOUTS_CONFIG,
|
|
177
|
-
|
|
178
|
-
...stencilConfig,
|
|
164
|
+
...config,
|
|
179
165
|
...cliOptions,
|
|
180
166
|
...answers,
|
|
181
167
|
};
|
package/lib/stencil-push.js
CHANGED
|
@@ -18,7 +18,7 @@ function stencilPush(options = {}, callback) {
|
|
|
18
18
|
utils.pollForJobCompletion((data) => ({ themeId: data.theme_id })),
|
|
19
19
|
utils.promptUserWhetherToApplyTheme,
|
|
20
20
|
utils.getChannels,
|
|
21
|
-
utils.
|
|
21
|
+
utils.promptUserForChannels,
|
|
22
22
|
utils.getVariations,
|
|
23
23
|
utils.promptUserForVariation,
|
|
24
24
|
utils.requestToApplyVariationWithRetrys(),
|
|
@@ -275,13 +275,14 @@ utils.getChannels = async (options) => {
|
|
|
275
275
|
const {
|
|
276
276
|
config: { accessToken },
|
|
277
277
|
channelId,
|
|
278
|
+
channelIds,
|
|
278
279
|
storeHash,
|
|
279
280
|
applyTheme,
|
|
280
281
|
} = options;
|
|
281
282
|
|
|
282
283
|
const apiHost = options.apiHost || options.config.apiHost;
|
|
283
284
|
|
|
284
|
-
if (!applyTheme || channelId) {
|
|
285
|
+
if (!applyTheme || channelIds || channelId) {
|
|
285
286
|
return options;
|
|
286
287
|
}
|
|
287
288
|
|
|
@@ -338,6 +339,43 @@ utils.getVariations = async (options) => {
|
|
|
338
339
|
return { ...options, variations };
|
|
339
340
|
};
|
|
340
341
|
|
|
342
|
+
utils.promptUserForChannels = async (options) => {
|
|
343
|
+
const { applyTheme, channelIds, channels, allChannels } = options;
|
|
344
|
+
|
|
345
|
+
if (!applyTheme || channelIds) {
|
|
346
|
+
return options;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (allChannels) {
|
|
350
|
+
const allIds = channels.map((chanel) => chanel.channel_id);
|
|
351
|
+
return { ...options, channelIds: allIds };
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const selectedChannelIds = await utils.promptUserToSelectChannels(channels);
|
|
355
|
+
return { ...options, channelIds: selectedChannelIds };
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
utils.promptUserToSelectChannels = async (channels) => {
|
|
359
|
+
if (channels.length < 2) {
|
|
360
|
+
return [channels[0].channel_id];
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const questions = [
|
|
364
|
+
{
|
|
365
|
+
type: 'checkbox',
|
|
366
|
+
name: 'channelIds',
|
|
367
|
+
message: 'Which channel(s) would you like to use?',
|
|
368
|
+
choices: channels.map((channel) => ({
|
|
369
|
+
name: channel.url,
|
|
370
|
+
value: channel.channel_id,
|
|
371
|
+
})),
|
|
372
|
+
},
|
|
373
|
+
];
|
|
374
|
+
|
|
375
|
+
const answer = await Inquirer.prompt(questions);
|
|
376
|
+
return answer.channelIds;
|
|
377
|
+
};
|
|
378
|
+
|
|
341
379
|
utils.promptUserForChannel = async (options) => {
|
|
342
380
|
const { applyTheme, channelId, channels } = options;
|
|
343
381
|
|
|
@@ -414,18 +452,18 @@ utils.requestToApplyVariation = async (options) => {
|
|
|
414
452
|
config: { accessToken },
|
|
415
453
|
storeHash,
|
|
416
454
|
variationId,
|
|
417
|
-
|
|
455
|
+
channelIds,
|
|
418
456
|
} = options;
|
|
419
457
|
|
|
420
458
|
const apiHost = options.apiHost || options.config.apiHost;
|
|
421
459
|
|
|
422
460
|
if (options.applyTheme) {
|
|
423
461
|
await themeApiClient.activateThemeByVariationId({
|
|
424
|
-
|
|
462
|
+
variationId,
|
|
463
|
+
channelIds,
|
|
425
464
|
apiHost,
|
|
426
465
|
storeHash,
|
|
427
|
-
|
|
428
|
-
channelId,
|
|
466
|
+
accessToken,
|
|
429
467
|
});
|
|
430
468
|
}
|
|
431
469
|
|
package/lib/theme-api-client.js
CHANGED
|
@@ -65,33 +65,36 @@ async function checkCliVersion({ storeUrl, currentCliVersion = PACKAGE_INFO.vers
|
|
|
65
65
|
/**
|
|
66
66
|
* @param {object} options
|
|
67
67
|
* @param {string} options.variationId
|
|
68
|
-
* @param {
|
|
68
|
+
* @param {array} options.channelIds
|
|
69
69
|
* @param {string} options.apiHost
|
|
70
70
|
* @param {string} options.storeHash
|
|
71
71
|
* @param {string} options.accessToken
|
|
72
|
-
* @returns {Promise<
|
|
72
|
+
* @returns {Promise<Object[]>}
|
|
73
73
|
*/
|
|
74
74
|
async function activateThemeByVariationId({
|
|
75
75
|
variationId,
|
|
76
|
-
|
|
76
|
+
channelIds,
|
|
77
77
|
apiHost,
|
|
78
78
|
storeHash,
|
|
79
79
|
accessToken,
|
|
80
80
|
}) {
|
|
81
81
|
try {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
82
|
+
const promises = channelIds.map((id) =>
|
|
83
|
+
networkUtils.sendApiRequest({
|
|
84
|
+
url: `${apiHost}/stores/${storeHash}/v3/themes/actions/activate`,
|
|
85
|
+
headers: {
|
|
86
|
+
'content-type': 'application/json',
|
|
87
|
+
},
|
|
88
|
+
method: 'POST',
|
|
89
|
+
accessToken,
|
|
90
|
+
data: {
|
|
91
|
+
variation_id: variationId,
|
|
92
|
+
channel_id: Number(id),
|
|
93
|
+
which: 'original',
|
|
94
|
+
},
|
|
95
|
+
}),
|
|
96
|
+
);
|
|
97
|
+
return Promise.all(promises);
|
|
95
98
|
} catch (err) {
|
|
96
99
|
err.name =
|
|
97
100
|
err.response && err.response.status === 504
|
package/lib/utils/frontmatter.js
CHANGED
package/package-lock.json
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bigcommerce/stencil-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.1",
|
|
4
4
|
"description": "CLI tool to run BigCommerce Stores locally for theme development.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"engines": {
|
|
7
|
-
"node": "^10.17 || ^12"
|
|
7
|
+
"node": "^10.17 || ^12",
|
|
8
|
+
"npm": ">=v6.11.3 <7.0.0"
|
|
8
9
|
},
|
|
9
10
|
"scripts": {
|
|
10
11
|
"lint": "eslint . && prettier --check . --ignore-unknown",
|