@bigcommerce/stencil-cli 8.3.0 → 8.4.0

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.
Files changed (70) hide show
  1. package/bin/stencil-bundle.js +7 -18
  2. package/bin/stencil-debug.js +5 -9
  3. package/bin/stencil-download.js +7 -19
  4. package/bin/stencil-init.js +4 -8
  5. package/bin/stencil-pull.js +5 -11
  6. package/bin/stencil-push.js +5 -8
  7. package/bin/stencil-release.js +5 -10
  8. package/bin/stencil-scss-autofix.js +6 -11
  9. package/bin/stencil-start.js +6 -9
  10. package/bin/stencil.js +2 -3
  11. package/constants.js +9 -9
  12. package/lib/BuildConfigManager.js +25 -23
  13. package/lib/Cycles.js +3 -12
  14. package/lib/ScssValidator.js +5 -9
  15. package/lib/StencilCLISettings.js +1 -3
  16. package/lib/StencilConfigManager.js +6 -22
  17. package/lib/StencilDebug.js +7 -10
  18. package/lib/archiveManager.js +7 -23
  19. package/lib/bundle-validator.js +28 -64
  20. package/lib/cliCommon.js +11 -21
  21. package/lib/commander.js +2 -3
  22. package/lib/content-api-client.js +5 -13
  23. package/lib/css/compile.js +3 -6
  24. package/lib/graphql/query.js +5 -8
  25. package/lib/lang/validator.js +5 -11
  26. package/lib/lang-assembler.js +4 -10
  27. package/lib/lang-helper.js +3 -6
  28. package/lib/nodeSass/AutoFixer.js +10 -19
  29. package/lib/nodeSass/BaseFixer.js +5 -7
  30. package/lib/nodeSass/BaseRulesFixer.js +3 -8
  31. package/lib/nodeSass/CommaRemovalFixer.js +3 -8
  32. package/lib/nodeSass/ConditionalImportFixer.js +3 -9
  33. package/lib/nodeSass/UndefinedVariableFixer.js +3 -6
  34. package/lib/parse-json.js +10 -9
  35. package/lib/regions.js +3 -23
  36. package/lib/release/questions.js +3 -13
  37. package/lib/release/release.js +16 -55
  38. package/lib/spinner.js +1 -2
  39. package/lib/stencil-bundle.js +15 -75
  40. package/lib/stencil-download.js +5 -6
  41. package/lib/stencil-download.utils.js +5 -18
  42. package/lib/stencil-init.js +8 -24
  43. package/lib/stencil-pull.js +4 -5
  44. package/lib/stencil-pull.utils.js +5 -28
  45. package/lib/stencil-push.js +3 -4
  46. package/lib/stencil-push.utils.js +12 -102
  47. package/lib/stencil-start.js +19 -48
  48. package/lib/store-settings-api-client.js +4 -7
  49. package/lib/template-assembler.js +6 -45
  50. package/lib/theme-api-client.js +7 -30
  51. package/lib/theme-config.js +16 -59
  52. package/lib/utils/NetworkUtils.js +6 -16
  53. package/lib/utils/asyncUtils.js +2 -3
  54. package/lib/utils/frontmatter.js +4 -5
  55. package/lib/utils/fsUtils.js +6 -10
  56. package/lib/validator/schema-translations.js +5 -7
  57. package/package.json +11 -8
  58. package/server/config.js +3 -7
  59. package/server/index.js +29 -29
  60. package/server/lib/page-type-util.js +2 -5
  61. package/server/lib/show-logo.js +3 -3
  62. package/server/lib/utils.js +6 -11
  63. package/server/manifest.js +7 -11
  64. package/server/plugins/renderer/renderer.module.js +38 -100
  65. package/server/plugins/renderer/responses/index.js +7 -4
  66. package/server/plugins/renderer/responses/pencil-response.js +4 -32
  67. package/server/plugins/renderer/responses/raw-response.js +6 -14
  68. package/server/plugins/renderer/responses/redirect-response.js +1 -4
  69. package/server/plugins/router/router.module.js +9 -14
  70. package/server/plugins/theme-assets/theme-assets.module.js +15 -27
@@ -1,5 +1,4 @@
1
1
  const uuidRegExp = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-([0-9a-f]{12})';
2
-
3
2
  /**
4
3
  * Strip domain from the cookies header string
5
4
  *
@@ -13,7 +12,6 @@ function stripDomainFromCookies(cookies) {
13
12
  .replace(new RegExp('; SameSite=none', 'gi'), ''),
14
13
  );
15
14
  }
16
-
17
15
  /**
18
16
  * Strip domain from redirectUrl if it matches the current storeUrl, if not, leave it.
19
17
  *
@@ -25,19 +23,15 @@ function normalizeRedirectUrl(redirectUrl, config) {
25
23
  if (!redirectUrl || !redirectUrl.startsWith('http')) {
26
24
  return redirectUrl; // already stripped, skip
27
25
  }
28
-
29
26
  const storeHost = new URL(config.normalStoreUrl).host;
30
27
  const secureStoreHost = new URL(config.storeUrl).host;
31
28
  const redirectUrlObj = new URL(redirectUrl);
32
-
33
29
  if (redirectUrlObj.host === storeHost || redirectUrlObj.host === secureStoreHost) {
34
30
  // Need to strip
35
31
  return redirectUrlObj.pathname + redirectUrlObj.search + redirectUrlObj.hash;
36
32
  }
37
-
38
33
  return redirectUrl; // Different host, shouldn't strip
39
34
  }
40
-
41
35
  /**
42
36
  * Convert a number to uuid
43
37
  *
@@ -48,7 +42,6 @@ function int2uuid(number) {
48
42
  const id = `000000000000${number}`.substr(-12);
49
43
  return `00000000-0000-0000-0000-${id}`;
50
44
  }
51
-
52
45
  /**
53
46
  * Convert a uuid to int
54
47
  *
@@ -57,15 +50,17 @@ function int2uuid(number) {
57
50
  */
58
51
  function uuid2int(uuid) {
59
52
  const match = uuid.match(new RegExp(uuidRegExp));
60
-
61
53
  if (!match) {
62
54
  throw new Error(`Not uuid match for ${uuid}`);
63
55
  }
64
-
65
56
  return match ? parseInt(match[1], 10) : 0;
66
57
  }
67
-
68
- module.exports = {
58
+ export { stripDomainFromCookies };
59
+ export { normalizeRedirectUrl };
60
+ export { int2uuid };
61
+ export { uuid2int };
62
+ export { uuidRegExp };
63
+ export default {
69
64
  stripDomainFromCookies,
70
65
  normalizeRedirectUrl,
71
66
  int2uuid,
@@ -1,10 +1,9 @@
1
- const Confidence = require('confidence');
2
- const config = require('./config');
1
+ import Confidence from 'confidence';
2
+ import * as config from './config.js';
3
3
 
4
4
  const criteria = {
5
5
  env: process.env.NODE_ENV,
6
6
  };
7
-
8
7
  const manifest = {
9
8
  $meta: 'Stencil',
10
9
  server: {
@@ -17,15 +16,12 @@ const manifest = {
17
16
  '@hapi/inert': {},
18
17
  '@hapi/h2o2': {},
19
18
  // First Party Plugins
20
- './plugins/renderer/renderer.module': {},
21
- './plugins/router/router.module': {},
22
- './plugins/theme-assets/theme-assets.module': {},
19
+ './plugins/renderer/renderer.module.js': {},
20
+ './plugins/router/router.module.js': {},
21
+ './plugins/theme-assets/theme-assets.module.js': {},
23
22
  },
24
23
  },
25
24
  };
26
-
27
25
  const store = new Confidence.Store(manifest);
28
-
29
- exports.get = (key) => store.get(key, criteria);
30
-
31
- exports.meta = (key) => store.meta(key, criteria);
26
+ export const get = (key) => store.get(key, criteria);
27
+ export const meta = (key) => store.meta(key, criteria);
@@ -1,40 +1,35 @@
1
- const _ = require('lodash');
2
- const Boom = require('@hapi/boom');
3
- const cache = require('memory-cache');
4
- const Crypto = require('crypto');
5
- const Frontmatter = require('front-matter');
6
- const path = require('path');
7
- const { promisify } = require('util');
8
-
9
- const langAssembler = require('../../../lib/lang-assembler');
10
- const { RawResponse, RedirectResponse, PencilResponse } = require('./responses');
11
- const templateAssembler = require('../../../lib/template-assembler');
12
- const utils = require('../../lib/utils');
13
- const { readFromStream } = require('../../../lib/utils/asyncUtils');
14
- const NetworkUtils = require('../../../lib/utils/NetworkUtils');
15
- const contentApiClient = require('../../../lib/content-api-client');
16
- const { getPageType } = require('../../lib/page-type-util');
17
- const {
1
+ import { defaultsDeep, omit, isObject, extend, isPlainObject, mapValues, findKey } from 'lodash-es';
2
+ import Boom from '@hapi/boom';
3
+ import cache from 'memory-cache';
4
+ import Crypto from 'crypto';
5
+ import Frontmatter from 'front-matter';
6
+ import path from 'path';
7
+ import { promisify } from 'util';
8
+ import langAssembler from '../../../lib/lang-assembler.js';
9
+ import { RawResponse, RedirectResponse, PencilResponse } from './responses/index.js';
10
+ import templateAssembler from '../../../lib/template-assembler.js';
11
+ import { int2uuid, stripDomainFromCookies, normalizeRedirectUrl } from '../../lib/utils.js';
12
+ import { readFromStream } from '../../../lib/utils/asyncUtils.js';
13
+ import NetworkUtils from '../../../lib/utils/NetworkUtils.js';
14
+ import contentApiClient from '../../../lib/content-api-client.js';
15
+ import { getPageType } from '../../lib/page-type-util.js';
16
+ import {
18
17
  frontmatterRegex,
19
18
  getFrontmatterContent,
20
19
  interpolateThemeSettings,
21
- } = require('../../../lib/utils/frontmatter');
20
+ } from '../../../lib/utils/frontmatter.js';
22
21
 
23
22
  const networkUtils = new NetworkUtils();
24
-
25
23
  const internals = {
26
24
  options: {},
27
- cacheTTL: 1000 * 15, // 15 seconds
28
- graphQLCacheTTL: 1000 * 300, // 5 minutes
25
+ cacheTTL: 1000 * 15,
26
+ graphQLCacheTTL: 1000 * 300,
29
27
  validCustomTemplatePageTypes: ['brand', 'category', 'page', 'product'],
30
28
  };
31
-
32
29
  function register(server, options) {
33
- internals.options = _.defaultsDeep(options, internals.options);
34
-
30
+ internals.options = defaultsDeep(options, internals.options);
35
31
  server.expose('implementation', internals.implementation);
36
32
  }
37
-
38
33
  /**
39
34
  * Renderer Route Handler
40
35
  *
@@ -43,16 +38,13 @@ function register(server, options) {
43
38
  */
44
39
  internals.implementation = async (request, h) => {
45
40
  let response;
46
-
47
41
  try {
48
42
  response = await internals.getResponse(request);
49
43
  } catch (err) {
50
44
  throw Boom.badImplementation(err);
51
45
  }
52
-
53
46
  return response.respond(request, h);
54
47
  };
55
-
56
48
  /**
57
49
  * Creates a hash
58
50
  *
@@ -62,7 +54,6 @@ internals.implementation = async (request, h) => {
62
54
  internals.sha1sum = (input) => {
63
55
  return Crypto.createHash('sha1').update(JSON.stringify(input)).digest('hex');
64
56
  };
65
-
66
57
  /**
67
58
  * Fetches data from Stapler
68
59
  *
@@ -77,7 +68,6 @@ internals.getResponse = async (request) => {
77
68
  });
78
69
  const withoutPageQuery = new URL(fullUrl.toString());
79
70
  withoutPageQuery.searchParams.delete('page');
80
-
81
71
  const httpOpts = {
82
72
  url: withoutPageQuery.toString(),
83
73
  headers: internals.buildReqHeaders({
@@ -88,20 +78,18 @@ internals.getResponse = async (request) => {
88
78
  accessToken: internals.options.accessToken,
89
79
  data: request.payload,
90
80
  method: request.method,
91
- maxRedirects: 0, // handle the redirects manually to handle the redirect location
81
+ maxRedirects: 0,
92
82
  // If the response is an image it will be parsed wrongly, so we receive a raw data (stream)
93
83
  // and perform it manually depending on contentType later
94
84
  responseType: 'stream',
95
85
  validateStatus: (status) => status >= 200 && status < 500,
96
86
  };
97
-
98
87
  const responseArgs = {
99
88
  httpOpts: { ...httpOpts, url: fullUrl.toString() },
100
89
  storeUrlObj,
101
90
  };
102
-
103
91
  // check request signature and use cache, if available
104
- const httpOptsSignature = _.omit(httpOpts.headers, ['cookie']);
92
+ const httpOptsSignature = omit(httpOpts.headers, ['cookie']);
105
93
  const requestSignature = internals.sha1sum(httpOpts.url) + internals.sha1sum(httpOptsSignature);
106
94
  const cachedResponse = cache.get(requestSignature);
107
95
  if (cachedResponse && request.method === 'get' && internals.options.useCache) {
@@ -117,22 +105,18 @@ internals.getResponse = async (request) => {
117
105
  cache.clear();
118
106
  }
119
107
  const response = await networkUtils.sendApiRequest(httpOpts);
120
-
121
108
  internals.processResHeaders(response.headers);
122
-
123
109
  // Redirect
124
110
  if (response.status >= 301 && response.status <= 303) {
125
111
  return internals.redirect(response, request);
126
112
  }
127
113
  // Else response is success (2xx), need to handle it further
128
114
  // (5xx will be just thrown by axios)
129
-
130
115
  const contentType = response.headers['content-type'] || '';
131
116
  const isResponseJson = contentType.toLowerCase().includes('application/json');
132
117
  const bcAppData = isResponseJson
133
118
  ? JSON.parse(await readFromStream(response.data))
134
119
  : response.data;
135
-
136
120
  // cache response
137
121
  cache.put(
138
122
  requestSignature,
@@ -144,7 +128,6 @@ internals.getResponse = async (request) => {
144
128
  );
145
129
  return internals.parseResponse(bcAppData, request, response, responseArgs);
146
130
  };
147
-
148
131
  /**
149
132
  * parses the response from bc app
150
133
  *
@@ -156,22 +139,17 @@ internals.getResponse = async (request) => {
156
139
  */
157
140
  internals.parseResponse = async (bcAppData, request, response, responseArgs) => {
158
141
  const { httpOpts, storeUrlObj } = responseArgs;
159
-
160
142
  if (typeof bcAppData !== 'object' || !('pencil_response' in bcAppData)) {
161
143
  delete response.headers['x-frame-options'];
162
-
163
144
  // this is a raw response not emitted by TemplateEngine
164
145
  return new RawResponse(bcAppData, response.headers, response.status);
165
146
  }
166
-
167
147
  const configuration = await request.app.themeConfig.getConfig();
168
-
169
148
  // If a remote call, no need to do a second call to get the data,
170
149
  // it has already come back
171
150
  if (bcAppData.remote) {
172
151
  return internals.getPencilResponse(bcAppData, request, response, configuration);
173
152
  }
174
-
175
153
  httpOpts.headers = internals.buildReqHeaders({
176
154
  request,
177
155
  stencilOptions: { get_data_only: true },
@@ -181,47 +159,37 @@ internals.parseResponse = async (bcAppData, request, response, responseArgs) =>
181
159
  },
182
160
  });
183
161
  httpOpts.responseType = 'json'; // In the second request we always expect json
184
-
185
162
  // create request signature for caching
186
- const httpOptsSignature = internals.sha1sum(_.omit(httpOpts.headers, ['cookie']));
163
+ const httpOptsSignature = internals.sha1sum(omit(httpOpts.headers, ['cookie']));
187
164
  const urlSignature = internals.sha1sum(httpOpts.url);
188
165
  const dataRequestSignature = `bcapp:${urlSignature}${httpOptsSignature}`;
189
166
  const cachedResponse2 = cache.get(dataRequestSignature);
190
-
191
167
  let response2;
192
168
  // check request signature and use cache, if available
193
169
  if (internals.options.useCache && cachedResponse2) {
194
170
  ({ response2 } = cachedResponse2);
195
171
  } else {
196
172
  response2 = await networkUtils.sendApiRequest(httpOpts);
197
-
198
173
  internals.processResHeaders(response2.headers);
199
-
200
174
  // Response is a redirect
201
175
  if (response2.status >= 301 && response2.status <= 303) {
202
176
  return internals.redirect(response2, request);
203
177
  }
204
-
205
178
  if (response2.data && response2.data.status === 500) {
206
179
  throw new Error('The BigCommerce server responded with a 500 error');
207
180
  }
208
-
209
181
  cache.put(dataRequestSignature, { response2 }, internals.cacheTTL);
210
182
  }
211
-
212
183
  const templateFile = response2.data.template_file;
213
184
  const entityId = response2.data.entity_id;
214
-
215
185
  const pageType = getPageType(templateFile);
216
186
  let regionResponse = [];
217
-
218
187
  if (pageType) {
219
188
  // create request signature and use cache, if available
220
189
  const graphQLUrlSignature = internals.sha1sum(internals.options.storeUrl + '/graphql');
221
190
  const graphQLQuerySignature = internals.sha1sum(pageType + entityId);
222
191
  const graphQLDataReqSignature = `graphql:${graphQLUrlSignature + graphQLQuerySignature}`;
223
192
  const cachedGraphQLResponse = cache.get(graphQLDataReqSignature);
224
-
225
193
  if (internals.options.useCache && cachedGraphQLResponse) {
226
194
  ({ regionResponse } = cachedGraphQLResponse);
227
195
  } else {
@@ -239,19 +207,15 @@ internals.parseResponse = async (bcAppData, request, response, responseArgs) =>
239
207
  pageType,
240
208
  });
241
209
  }
242
-
243
210
  cache.put(graphQLDataReqSignature, { regionResponse }, internals.graphQLCacheTTL);
244
211
  }
245
212
  }
246
-
247
213
  const formattedRegions = {};
248
-
249
214
  if (typeof regionResponse.renderedRegions !== 'undefined') {
250
215
  regionResponse.renderedRegions.forEach((region) => {
251
216
  formattedRegions[region.name] = region.html;
252
217
  });
253
218
  }
254
-
255
219
  return internals.getPencilResponse(
256
220
  response2.data,
257
221
  request,
@@ -260,7 +224,6 @@ internals.parseResponse = async (bcAppData, request, response, responseArgs) =>
260
224
  formattedRegions,
261
225
  );
262
226
  };
263
-
264
227
  /**
265
228
  * Get the resource configuration (front-matter) from the main template
266
229
  * or from the header stencil-config for ajax requests
@@ -273,7 +236,6 @@ internals.getResourceConfig = (data, request, configuration) => {
273
236
  const missingThemeSettingsRegex = /{{\\s*?theme_settings\\..+?\\s*?}}/g;
274
237
  let resourcesConfig = {};
275
238
  const templatePath = internals.getTemplatePath(request.path, data);
276
-
277
239
  // If the requested template is not an array, we parse the Frontmatter
278
240
  // If it is an array, then it's an ajax request using `render_with` with multiple components
279
241
  // which don't have Frontmatter and needs to get it's config from the `stencil-config` header.
@@ -282,7 +244,6 @@ internals.getResourceConfig = (data, request, configuration) => {
282
244
  internals.getThemeTemplatesPath(),
283
245
  templatePath,
284
246
  );
285
-
286
247
  let frontmatterContent = getFrontmatterContent(rawTemplate);
287
248
  if (frontmatterContent !== null) {
288
249
  frontmatterContent = interpolateThemeSettings(
@@ -294,12 +255,11 @@ internals.getResourceConfig = (data, request, configuration) => {
294
255
  // Replace the frontmatter with the newly interpolated version
295
256
  rawTemplate = rawTemplate.replace(frontmatterRegex, frontmatterContent);
296
257
  }
297
-
298
258
  const frontmatter = Frontmatter(rawTemplate); // Set the config
299
259
  resourcesConfig = frontmatter.attributes;
300
260
  // Merge the frontmatter config with the global resource config
301
- if (_.isObject(configuration.resources)) {
302
- resourcesConfig = _.extend({}, configuration.resources, resourcesConfig);
261
+ if (isObject(configuration.resources)) {
262
+ resourcesConfig = extend({}, configuration.resources, resourcesConfig);
303
263
  }
304
264
  } else if (request.headers['stencil-config']) {
305
265
  try {
@@ -308,10 +268,8 @@ internals.getResourceConfig = (data, request, configuration) => {
308
268
  resourcesConfig = {};
309
269
  }
310
270
  }
311
-
312
271
  return resourcesConfig;
313
272
  };
314
-
315
273
  /**
316
274
  * Redirects based on the response & request
317
275
  *
@@ -321,17 +279,13 @@ internals.getResourceConfig = (data, request, configuration) => {
321
279
  */
322
280
  internals.redirect = async (response, request) => {
323
281
  const { location } = response.headers;
324
-
325
282
  if (!location) {
326
283
  throw new Error('StatusCode is set to 30x but there is no location header to redirect to.');
327
284
  }
328
-
329
- response.headers.location = utils.normalizeRedirectUrl(location, request.app);
330
-
285
+ response.headers.location = normalizeRedirectUrl(location, request.app);
331
286
  // return a redirect response
332
287
  return new RedirectResponse(location, response.headers, response.status);
333
288
  };
334
-
335
289
  /**
336
290
  *
337
291
  * @param {string} requestPath
@@ -342,30 +296,25 @@ internals.getTemplatePath = (requestPath, data) => {
342
296
  const customLayouts = internals.options.customLayouts || {};
343
297
  const pageType = data.page_type;
344
298
  let templatePath;
345
-
346
299
  if (
347
300
  internals.validCustomTemplatePageTypes.includes(pageType) &&
348
- _.isPlainObject(customLayouts[pageType])
301
+ isPlainObject(customLayouts[pageType])
349
302
  ) {
350
- templatePath = _.findKey(customLayouts[pageType], (paths) => {
303
+ templatePath = findKey(customLayouts[pageType], (paths) => {
351
304
  // Can be either string or Array, so normalize to Arrays
352
305
  const normalizedPaths = typeof paths === 'string' ? [paths] : paths;
353
-
354
306
  const matches = normalizedPaths.filter((url) => {
355
307
  // remove trailing slashes to compare
356
308
  return url.replace(/\/$/, '') === requestPath.replace(/\/$/, '');
357
309
  });
358
-
359
310
  return matches.length > 0;
360
311
  });
361
-
362
312
  if (templatePath) {
363
313
  templatePath = path.join('pages/custom', pageType, templatePath.replace(/\.html$/, ''));
364
314
  }
365
315
  }
366
316
  return templatePath || data.template_file;
367
317
  };
368
-
369
318
  function getAcceptLanguageHeader(request) {
370
319
  if (
371
320
  internals.options.storeSettingsLocale.shopper_language_selection_method ===
@@ -375,7 +324,6 @@ function getAcceptLanguageHeader(request) {
375
324
  }
376
325
  return request.headers['accept-language'].toLowerCase();
377
326
  }
378
-
379
327
  /**
380
328
  * Creates a new Pencil Response object and returns it.
381
329
  *
@@ -395,13 +343,12 @@ internals.getPencilResponse = (data, request, response, configuration, renderedR
395
343
  ...data.context.settings,
396
344
  // change cdn settings to serve local assets
397
345
  cdn_url: '',
398
- theme_version_id: utils.int2uuid(1),
399
- theme_config_id: utils.int2uuid(request.app.themeConfig.variationIndex + 1),
346
+ theme_version_id: int2uuid(1),
347
+ theme_config_id: int2uuid(request.app.themeConfig.variationIndex + 1),
400
348
  theme_session_id: null,
401
349
  maintenance: { secure_path: `http://localhost:${internals.options.port}` },
402
350
  },
403
351
  };
404
-
405
352
  return new PencilResponse(
406
353
  {
407
354
  template_file: internals.getTemplatePath(request.path, data),
@@ -419,7 +366,6 @@ internals.getPencilResponse = (data, request, response, configuration, renderedR
419
366
  internals.themeAssembler,
420
367
  );
421
368
  };
422
-
423
369
  /**
424
370
  * Get headers from request and return a new object with processed headers
425
371
  *
@@ -441,21 +387,16 @@ internals.buildReqHeaders = ({
441
387
  const currentOptions = request.headers['stencil-options']
442
388
  ? JSON.parse(request.headers['stencil-options'])
443
389
  : {};
444
-
445
390
  const headers = {
446
391
  'stencil-options': JSON.stringify({ ...stencilOptions, ...currentOptions }),
447
392
  'accept-encoding': 'identity',
448
393
  };
449
-
450
394
  const config = request.headers['stencil-config'];
451
-
452
395
  if ((!config || config === '{}') && stencilConfig) {
453
396
  headers['stencil-config'] = JSON.stringify(stencilConfig);
454
397
  }
455
-
456
398
  return { ...request.headers, ...headers, ...extraHeaders };
457
399
  };
458
-
459
400
  /**
460
401
  * Process headers from Fetch response
461
402
  *
@@ -465,10 +406,9 @@ internals.buildReqHeaders = ({
465
406
  internals.processResHeaders = (headers) => {
466
407
  if (headers && headers['set-cookie']) {
467
408
  // eslint-disable-next-line no-param-reassign
468
- headers['set-cookie'] = utils.stripDomainFromCookies(headers['set-cookie']);
409
+ headers['set-cookie'] = stripDomainFromCookies(headers['set-cookie']);
469
410
  }
470
411
  };
471
-
472
412
  /**
473
413
  * Theme assembler interface for paper
474
414
  * @type {Object}
@@ -479,17 +419,14 @@ internals.themeAssembler = {
479
419
  internals.getThemeTemplatesPath(),
480
420
  templatesPath,
481
421
  );
482
-
483
422
  if (templates[templatesPath]) {
484
423
  // Check if the string includes frontmatter configuration and remove it
485
424
  const match = templates[templatesPath].match(/---\r?\n[\S\s]*\r?\n---\r?\n([\S\s]*)$/);
486
-
487
425
  if (match && match[1]) {
488
426
  // eslint-disable-next-line prefer-destructuring
489
427
  templates[templatesPath] = match[1];
490
428
  }
491
429
  }
492
-
493
430
  return processor(templates);
494
431
  },
495
432
  getTranslations: () => {
@@ -498,18 +435,19 @@ internals.themeAssembler = {
498
435
  if (err) {
499
436
  return reject(err);
500
437
  }
501
- return resolve(_.mapValues(translations, (locales) => JSON.parse(locales)));
438
+ return resolve(mapValues(translations, (locales) => JSON.parse(locales)));
502
439
  });
503
440
  });
504
441
  },
505
442
  };
506
-
507
443
  internals.getThemeTemplatesPath = () => {
508
444
  return path.join(internals.options.themePath, 'templates');
509
445
  };
510
-
511
- module.exports = {
446
+ export const name = 'Renderer';
447
+ export const version = '0.0.1';
448
+ export { register };
449
+ export default {
512
450
  register,
513
- name: 'Renderer',
514
- version: '0.0.1',
451
+ name,
452
+ version,
515
453
  };
@@ -1,8 +1,11 @@
1
- const PencilResponse = require('./pencil-response');
2
- const RawResponse = require('./raw-response');
3
- const RedirectResponse = require('./redirect-response');
1
+ import PencilResponse from './pencil-response.js';
2
+ import RawResponse from './raw-response.js';
3
+ import RedirectResponse from './redirect-response.js';
4
4
 
5
- module.exports = {
5
+ export { PencilResponse };
6
+ export { RawResponse };
7
+ export { RedirectResponse };
8
+ export default {
6
9
  PencilResponse,
7
10
  RawResponse,
8
11
  RedirectResponse,