@bigcommerce/stencil-cli 3.8.0 → 3.8.4
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 +17 -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.utils.js +19 -14
- package/lib/theme-api-client.js +19 -16
- package/package-lock.json +615 -134
- package/package.json +3 -3
- package/server/plugins/theme-assets/theme-assets.module.js +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
### 3.8.4 (2022-01-13)
|
|
2
|
+
|
|
3
|
+
- fix: `stencil init` command including `apiHost` option is now recognized ([830](https://github.com/bigcommerce/stencil-cli/pull/830))
|
|
4
|
+
- feat: `stencil push` command allows to push a theme to multiple channels ([825](https://github.com/bigcommerce/stencil-cli/pull/825))
|
|
5
|
+
|
|
6
|
+
### 3.8.3 (2022-01-12)
|
|
7
|
+
|
|
8
|
+
- fix: add activate sass engine name logic ([837](https://github.com/bigcommerce/stencil-cli/pull/837))
|
|
9
|
+
|
|
10
|
+
### 3.8.2 (2022-01-11)
|
|
11
|
+
|
|
12
|
+
- fix: strf-9600 bump stencil styles version ([832](https://github.com/bigcommerce/stencil-cli/pull/832))
|
|
13
|
+
|
|
14
|
+
### 3.8.1 (2022-01-10)
|
|
15
|
+
|
|
16
|
+
- fix: Updated package.json to use colors 1.4.0 ([827](https://github.com/bigcommerce/stencil-cli/pull/827))
|
|
17
|
+
|
|
1
18
|
### 3.8.0 (2021-12-30)
|
|
2
19
|
|
|
3
20
|
- build(deps): bump axios from 0.21.4 to 0.24.0 ([821](https://github.com/bigcommerce/stencil-cli/pull/821))
|
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
|
};
|
|
@@ -274,14 +274,14 @@ utils.promptUserWhetherToApplyTheme = async (options) => {
|
|
|
274
274
|
utils.getChannels = async (options) => {
|
|
275
275
|
const {
|
|
276
276
|
config: { accessToken },
|
|
277
|
-
|
|
277
|
+
channelIds,
|
|
278
278
|
storeHash,
|
|
279
279
|
applyTheme,
|
|
280
280
|
} = options;
|
|
281
281
|
|
|
282
282
|
const apiHost = options.apiHost || options.config.apiHost;
|
|
283
283
|
|
|
284
|
-
if (!applyTheme ||
|
|
284
|
+
if (!applyTheme || channelIds) {
|
|
285
285
|
return options;
|
|
286
286
|
}
|
|
287
287
|
|
|
@@ -339,14 +339,19 @@ utils.getVariations = async (options) => {
|
|
|
339
339
|
};
|
|
340
340
|
|
|
341
341
|
utils.promptUserForChannel = async (options) => {
|
|
342
|
-
const { applyTheme,
|
|
342
|
+
const { applyTheme, channelIds, channels, allChannels } = options;
|
|
343
343
|
|
|
344
|
-
if (!applyTheme ||
|
|
344
|
+
if (!applyTheme || channelIds) {
|
|
345
345
|
return options;
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
-
|
|
349
|
-
|
|
348
|
+
if (allChannels) {
|
|
349
|
+
const allIds = channels.map((chanel) => chanel.channel_id);
|
|
350
|
+
return { ...options, channelIds: allIds };
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const selectedChannelIds = await utils.promptUserToSelectChannel(channels);
|
|
354
|
+
return { ...options, channelIds: selectedChannelIds };
|
|
350
355
|
};
|
|
351
356
|
|
|
352
357
|
utils.promptUserToSelectChannel = async (channels) => {
|
|
@@ -356,9 +361,9 @@ utils.promptUserToSelectChannel = async (channels) => {
|
|
|
356
361
|
|
|
357
362
|
const questions = [
|
|
358
363
|
{
|
|
359
|
-
type: '
|
|
360
|
-
name: '
|
|
361
|
-
message: 'Which channel would you like to use?',
|
|
364
|
+
type: 'checkbox',
|
|
365
|
+
name: 'channelIds',
|
|
366
|
+
message: 'Which channel(s) would you like to use?',
|
|
362
367
|
choices: channels.map((channel) => ({
|
|
363
368
|
name: channel.url,
|
|
364
369
|
value: channel.channel_id,
|
|
@@ -367,7 +372,7 @@ utils.promptUserToSelectChannel = async (channels) => {
|
|
|
367
372
|
];
|
|
368
373
|
|
|
369
374
|
const answer = await Inquirer.prompt(questions);
|
|
370
|
-
return answer.
|
|
375
|
+
return answer.channelIds;
|
|
371
376
|
};
|
|
372
377
|
|
|
373
378
|
utils.promptUserForVariation = async (options) => {
|
|
@@ -414,18 +419,18 @@ utils.requestToApplyVariation = async (options) => {
|
|
|
414
419
|
config: { accessToken },
|
|
415
420
|
storeHash,
|
|
416
421
|
variationId,
|
|
417
|
-
|
|
422
|
+
channelIds,
|
|
418
423
|
} = options;
|
|
419
424
|
|
|
420
425
|
const apiHost = options.apiHost || options.config.apiHost;
|
|
421
426
|
|
|
422
427
|
if (options.applyTheme) {
|
|
423
428
|
await themeApiClient.activateThemeByVariationId({
|
|
424
|
-
|
|
429
|
+
variationId,
|
|
430
|
+
channelIds,
|
|
425
431
|
apiHost,
|
|
426
432
|
storeHash,
|
|
427
|
-
|
|
428
|
-
channelId,
|
|
433
|
+
accessToken,
|
|
429
434
|
});
|
|
430
435
|
}
|
|
431
436
|
|
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
|