@bigcommerce/stencil-cli 8.10.2 → 8.10.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/lib/stencil-start.js
CHANGED
|
@@ -58,38 +58,35 @@ class StencilStart {
|
|
|
58
58
|
const initialStencilConfig = await this._stencilConfigManager.read();
|
|
59
59
|
// Use initial (before updates) port for BrowserSync
|
|
60
60
|
const browserSyncPort = cliOptions.port || initialStencilConfig.port;
|
|
61
|
-
const
|
|
61
|
+
const channelUrl = await this.getChannelUrl(initialStencilConfig, cliOptions);
|
|
62
62
|
const storeInfoFromAPI = await this._themeApiClient.checkCliVersion({
|
|
63
|
-
storeUrl:
|
|
63
|
+
storeUrl: channelUrl,
|
|
64
64
|
});
|
|
65
65
|
const updatedStencilConfig = this.updateStencilConfig(
|
|
66
66
|
initialStencilConfig,
|
|
67
67
|
storeInfoFromAPI,
|
|
68
68
|
browserSyncPort,
|
|
69
69
|
);
|
|
70
|
-
|
|
71
70
|
this._storeSettingsLocale = await this.getStoreSettingsLocale(
|
|
72
71
|
cliOptions,
|
|
73
72
|
updatedStencilConfig,
|
|
74
|
-
channelInfo.channel_id,
|
|
75
73
|
);
|
|
76
74
|
await this.startLocalServer(cliOptions, updatedStencilConfig);
|
|
77
75
|
this._logger.log(this.getStartUpInfo(updatedStencilConfig));
|
|
78
76
|
await this.startBrowserSync(cliOptions, browserSyncPort);
|
|
79
77
|
}
|
|
80
78
|
|
|
81
|
-
async getStoreSettingsLocale(cliOptions, stencilConfig
|
|
79
|
+
async getStoreSettingsLocale(cliOptions, stencilConfig) {
|
|
82
80
|
const { accessToken } = stencilConfig;
|
|
83
81
|
const apiHost = cliOptions.apiHost || stencilConfig.apiHost;
|
|
84
82
|
return this._storeSettingsApiClient.getStoreSettingsLocale({
|
|
85
83
|
storeHash: this.storeHash,
|
|
86
84
|
accessToken,
|
|
87
85
|
apiHost,
|
|
88
|
-
channelId,
|
|
89
86
|
});
|
|
90
87
|
}
|
|
91
88
|
|
|
92
|
-
async
|
|
89
|
+
async getChannelUrl(stencilConfig, cliOptions) {
|
|
93
90
|
const { accessToken } = stencilConfig;
|
|
94
91
|
const apiHost = cliOptions.apiHost || stencilConfig.apiHost;
|
|
95
92
|
this.storeHash = await this._themeApiClient.getStoreHash({
|
|
@@ -109,7 +106,7 @@ class StencilStart {
|
|
|
109
106
|
const foundChannel = channels.find(
|
|
110
107
|
(channel) => channel.channel_id === parseInt(channelId, 10),
|
|
111
108
|
);
|
|
112
|
-
return foundChannel
|
|
109
|
+
return foundChannel ? foundChannel.url : null;
|
|
113
110
|
}
|
|
114
111
|
|
|
115
112
|
/**
|
|
@@ -2,50 +2,29 @@ import 'colors';
|
|
|
2
2
|
import NetworkUtils from './utils/NetworkUtils.js';
|
|
3
3
|
|
|
4
4
|
const networkUtils = new NetworkUtils();
|
|
5
|
-
|
|
6
|
-
async function getStoreSettingsLocaleWithChannel({ apiHost, storeHash, accessToken, channelId }) {
|
|
7
|
-
let url = `${apiHost}/stores/${storeHash}/v3/settings/store/locale`;
|
|
8
|
-
if (channelId) {
|
|
9
|
-
url += `?channel_id=${channelId}`;
|
|
10
|
-
}
|
|
11
|
-
const response = await networkUtils.sendApiRequest({
|
|
12
|
-
url,
|
|
13
|
-
accessToken,
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
return response.data.data;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async function getStoreSettingsLocale({ apiHost, storeHash, accessToken, channelId }) {
|
|
5
|
+
async function getStoreSettingsLocale({ apiHost, storeHash, accessToken }) {
|
|
20
6
|
try {
|
|
21
|
-
|
|
22
|
-
apiHost
|
|
23
|
-
storeHash,
|
|
7
|
+
const response = await networkUtils.sendApiRequest({
|
|
8
|
+
url: `${apiHost}/stores/${storeHash}/v3/settings/store/locale`,
|
|
24
9
|
accessToken,
|
|
25
|
-
channelId,
|
|
26
10
|
});
|
|
27
|
-
|
|
28
|
-
if (!data) {
|
|
29
|
-
data = await getStoreSettingsLocaleWithChannel({ apiHost, storeHash, accessToken });
|
|
30
|
-
}
|
|
31
|
-
if (!data) {
|
|
11
|
+
if (!response.data.data) {
|
|
32
12
|
throw new Error('Received empty store locale in the server response'.red);
|
|
33
|
-
} else if (!data.default_shopper_language) {
|
|
13
|
+
} else if (!response.data.data.default_shopper_language) {
|
|
34
14
|
throw new Error(
|
|
35
15
|
'Received empty default_shopper_language field in the server response'.red,
|
|
36
16
|
);
|
|
37
|
-
} else if (!data.shopper_language_selection_method) {
|
|
17
|
+
} else if (!response.data.data.shopper_language_selection_method) {
|
|
38
18
|
throw new Error(
|
|
39
19
|
'Received empty shopper_language_selection_method field in the server response'.red,
|
|
40
20
|
);
|
|
41
21
|
}
|
|
42
|
-
return data;
|
|
22
|
+
return response.data.data;
|
|
43
23
|
} catch (err) {
|
|
44
24
|
err.name = 'StoreSettingsLocaleError';
|
|
45
25
|
throw err;
|
|
46
26
|
}
|
|
47
27
|
}
|
|
48
|
-
|
|
49
28
|
export { getStoreSettingsLocale };
|
|
50
29
|
export default {
|
|
51
30
|
getStoreSettingsLocale,
|
package/lib/utils/asyncUtils.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @module Contains helpers functions for working with
|
|
2
|
+
* @module Contains helpers functions for working with streams
|
|
3
3
|
*/
|
|
4
|
+
|
|
5
|
+
import { PassThrough } from 'stream';
|
|
6
|
+
|
|
4
7
|
/**
|
|
5
8
|
* WARNING! Can be used with text content only. Binary data (e.g. images) will get broken!
|
|
6
9
|
*
|
|
@@ -14,7 +17,38 @@ async function readFromStream(stream) {
|
|
|
14
17
|
}
|
|
15
18
|
return result;
|
|
16
19
|
}
|
|
17
|
-
|
|
20
|
+
|
|
21
|
+
function readStream(stream) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
let data = '';
|
|
24
|
+
stream.on('data', (chunk) => {
|
|
25
|
+
data += chunk;
|
|
26
|
+
});
|
|
27
|
+
stream.on('end', () => {
|
|
28
|
+
resolve(data);
|
|
29
|
+
});
|
|
30
|
+
stream.on('error', reject);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function tapStream(originalStream, onData) {
|
|
35
|
+
const tee = new PassThrough();
|
|
36
|
+
originalStream.pipe(tee);
|
|
37
|
+
|
|
38
|
+
let data = '';
|
|
39
|
+
tee.on('data', (chunk) => {
|
|
40
|
+
data += chunk;
|
|
41
|
+
});
|
|
42
|
+
tee.on('end', () => {
|
|
43
|
+
onData(data);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return tee; // Use this stream for downstream consumers
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { readFromStream, tapStream, readStream };
|
|
18
50
|
export default {
|
|
19
51
|
readFromStream,
|
|
52
|
+
tapStream,
|
|
53
|
+
readStream,
|
|
20
54
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bigcommerce/stencil-cli",
|
|
3
|
-
"version": "8.10.
|
|
3
|
+
"version": "8.10.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI tool to run BigCommerce Stores locally for theme development.",
|
|
6
6
|
"main": "index.js",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
],
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@bigcommerce/stencil-paper": "5.3.0",
|
|
54
|
-
"@bigcommerce/stencil-styles": "
|
|
54
|
+
"@bigcommerce/stencil-styles": "6.1.1",
|
|
55
55
|
"@hapi/boom": "^10.0.1",
|
|
56
56
|
"@hapi/glue": "^9.0.1",
|
|
57
57
|
"@hapi/h2o2": "^10.0.4",
|
|
@@ -9,7 +9,7 @@ import langAssembler from '../../../lib/lang-assembler.js';
|
|
|
9
9
|
import { RawResponse, RedirectResponse, PencilResponse } from './responses/index.js';
|
|
10
10
|
import templateAssembler from '../../../lib/template-assembler.js';
|
|
11
11
|
import { int2uuid, stripDomainFromCookies, normalizeRedirectUrl } from '../../lib/utils.js';
|
|
12
|
-
import { readFromStream } from '../../../lib/utils/asyncUtils.js';
|
|
12
|
+
import { readFromStream, readStream, tapStream } from '../../../lib/utils/asyncUtils.js';
|
|
13
13
|
import NetworkUtils from '../../../lib/utils/NetworkUtils.js';
|
|
14
14
|
import contentApiClient from '../../../lib/content-api-client.js';
|
|
15
15
|
import { getPageType } from '../../lib/page-type-util.js';
|
|
@@ -114,9 +114,17 @@ internals.getResponse = async (request) => {
|
|
|
114
114
|
// (5xx will be just thrown by axios)
|
|
115
115
|
const contentType = response.headers['content-type'] || '';
|
|
116
116
|
const isResponseJson = contentType.toLowerCase().includes('application/json');
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
const isWebDavRequest = request.path.startsWith('/content');
|
|
118
|
+
let bcAppData = response.data;
|
|
119
|
+
|
|
120
|
+
if (isResponseJson) {
|
|
121
|
+
bcAppData = JSON.parse(await readFromStream(response.data));
|
|
122
|
+
} else if (isWebDavRequest) {
|
|
123
|
+
const tappedStream = tapStream(response.data, (body) => {
|
|
124
|
+
return body;
|
|
125
|
+
});
|
|
126
|
+
bcAppData = await readStream(tappedStream);
|
|
127
|
+
}
|
|
120
128
|
// cache response
|
|
121
129
|
cache.put(
|
|
122
130
|
requestSignature,
|