@zengenti/contensis-react-base 4.0.0-beta.9 → 4.0.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 (212) hide show
  1. package/README.md +14 -1
  2. package/cjs/{App-vZrUfVgQ.js → App-CNylISW7.js} +546 -104
  3. package/cjs/App-CNylISW7.js.map +1 -0
  4. package/cjs/{ChangePassword.container-ECjEXixF.js → ChangePassword.container-C4Du3Wb1.js} +57 -50
  5. package/cjs/ChangePassword.container-C4Du3Wb1.js.map +1 -0
  6. package/cjs/{SSRContext-DVj_QAC1.js → ContensisDeliveryApi-MfcvdfDR.js} +32 -74
  7. package/cjs/ContensisDeliveryApi-MfcvdfDR.js.map +1 -0
  8. package/cjs/CookieConstants-DfPiWCRZ.js +12 -0
  9. package/cjs/CookieConstants-DfPiWCRZ.js.map +1 -0
  10. package/{esm/CookieHelper.class-FTURFpz3.js → cjs/CookieHelper.class-Det3qfdU.js} +4 -6
  11. package/cjs/CookieHelper.class-Det3qfdU.js.map +1 -0
  12. package/cjs/{RouteLoader-D5Yg7EB5.js → RouteLoader-DJeM8cym.js} +17 -9
  13. package/cjs/RouteLoader-DJeM8cym.js.map +1 -0
  14. package/cjs/SSRContext-tMufQDHY.js +116 -0
  15. package/cjs/SSRContext-tMufQDHY.js.map +1 -0
  16. package/cjs/ToJs-BsWqWjdm.js +23 -0
  17. package/cjs/ToJs-BsWqWjdm.js.map +1 -0
  18. package/cjs/{VersionInfo-B_dKCubg.js → VersionInfo-zFPsvS8q.js} +3 -25
  19. package/cjs/VersionInfo-zFPsvS8q.js.map +1 -0
  20. package/cjs/client.js +63 -65
  21. package/cjs/client.js.map +1 -1
  22. package/cjs/contensis-react-base.js +208 -119
  23. package/cjs/contensis-react-base.js.map +1 -1
  24. package/cjs/i18n.js +75 -0
  25. package/cjs/i18n.js.map +1 -0
  26. package/cjs/{ToJs-C9jwV7YB.js → matchGroups-dqONU-vY.js} +2 -22
  27. package/cjs/matchGroups-dqONU-vY.js.map +1 -0
  28. package/cjs/redux.js +8 -6
  29. package/cjs/redux.js.map +1 -1
  30. package/cjs/routing.js +15 -7
  31. package/cjs/routing.js.map +1 -1
  32. package/cjs/{sagas-BVX4Ps1e.js → sagas-BCy9u6zA.js} +523 -375
  33. package/cjs/sagas-BCy9u6zA.js.map +1 -0
  34. package/cjs/search.js +54 -29
  35. package/cjs/search.js.map +1 -1
  36. package/cjs/{selectors-wCs5fHD4.js → selectors-BrxJ8-F8.js} +27 -6
  37. package/cjs/selectors-BrxJ8-F8.js.map +1 -0
  38. package/cjs/selectors-DAQR0uZa.js +18 -0
  39. package/cjs/selectors-DAQR0uZa.js.map +1 -0
  40. package/cjs/slice-5xJMH24n.js +69 -0
  41. package/cjs/slice-5xJMH24n.js.map +1 -0
  42. package/cjs/{store-D07FOXvM.js → store-B7SJs5Hf.js} +64 -5
  43. package/cjs/store-B7SJs5Hf.js.map +1 -0
  44. package/cjs/urls-DGZlAs0y.js +25 -0
  45. package/cjs/urls-DGZlAs0y.js.map +1 -0
  46. package/cjs/user.js +20 -17
  47. package/cjs/user.js.map +1 -1
  48. package/cjs/util-eOjxDjxF.js +148 -0
  49. package/cjs/util-eOjxDjxF.js.map +1 -0
  50. package/cjs/util.js +80 -22
  51. package/cjs/util.js.map +1 -1
  52. package/cjs/{version-CM-bJ62L.js → version-rFG9Y6_B.js} +2 -2
  53. package/cjs/{version-CM-bJ62L.js.map → version-rFG9Y6_B.js.map} +1 -1
  54. package/cjs/{version-B7XFkBhY.js → version-yjHMrfVz.js} +15 -16
  55. package/cjs/version-yjHMrfVz.js.map +1 -0
  56. package/esm/{App-DLZweVSp.js → App-Bvs7Km54.js} +507 -66
  57. package/esm/App-Bvs7Km54.js.map +1 -0
  58. package/esm/{ChangePassword.container-BgzIy8dA.js → ChangePassword.container-CUBtn82K.js} +19 -13
  59. package/esm/ChangePassword.container-CUBtn82K.js.map +1 -0
  60. package/esm/{SSRContext-BE8ElZ3X.js → ContensisDeliveryApi-LWYXevZ1.js} +30 -67
  61. package/esm/ContensisDeliveryApi-LWYXevZ1.js.map +1 -0
  62. package/esm/CookieConstants-DEmbwzYr.js +7 -0
  63. package/esm/CookieConstants-DEmbwzYr.js.map +1 -0
  64. package/{cjs/CookieHelper.class-C3Eqoze9.js → esm/CookieHelper.class-C6rTRl_1.js} +2 -14
  65. package/esm/CookieHelper.class-C6rTRl_1.js.map +1 -0
  66. package/esm/{RouteLoader-xeQBXywk.js → RouteLoader-CzrlySZf.js} +14 -6
  67. package/esm/RouteLoader-CzrlySZf.js.map +1 -0
  68. package/esm/SSRContext-Bxtg1KGv.js +106 -0
  69. package/esm/SSRContext-Bxtg1KGv.js.map +1 -0
  70. package/esm/ToJs-BnRRHk6f.js +17 -0
  71. package/esm/ToJs-BnRRHk6f.js.map +1 -0
  72. package/esm/{VersionInfo-Cno7K0OA.js → VersionInfo-By2ZCZOh.js} +4 -24
  73. package/esm/VersionInfo-By2ZCZOh.js.map +1 -0
  74. package/esm/client.js +63 -64
  75. package/esm/client.js.map +1 -1
  76. package/esm/contensis-react-base.js +201 -114
  77. package/esm/contensis-react-base.js.map +1 -1
  78. package/esm/i18n.js +64 -0
  79. package/esm/i18n.js.map +1 -0
  80. package/esm/{ToJs-CNzfvyxJ.js → matchGroups-_w8BwzCC.js} +3 -18
  81. package/esm/matchGroups-_w8BwzCC.js.map +1 -0
  82. package/esm/redux.js +11 -8
  83. package/esm/redux.js.map +1 -1
  84. package/esm/routing.js +14 -7
  85. package/esm/routing.js.map +1 -1
  86. package/esm/{sagas-JI51CS37.js → sagas-Fr9yRduO.js} +511 -362
  87. package/esm/sagas-Fr9yRduO.js.map +1 -0
  88. package/esm/search.js +73 -47
  89. package/esm/search.js.map +1 -1
  90. package/esm/{selectors-DO2ocdOp.js → selectors-8ROQrTd7.js} +25 -7
  91. package/esm/selectors-8ROQrTd7.js.map +1 -0
  92. package/esm/selectors-DcmvOeX2.js +10 -0
  93. package/esm/selectors-DcmvOeX2.js.map +1 -0
  94. package/esm/slice-C6JLQik8.js +63 -0
  95. package/esm/slice-C6JLQik8.js.map +1 -0
  96. package/esm/{store-3u0RzHZ0.js → store-B4IrBYHm.js} +64 -6
  97. package/esm/store-B4IrBYHm.js.map +1 -0
  98. package/esm/urls-tLxo_skx.js +22 -0
  99. package/esm/urls-tLxo_skx.js.map +1 -0
  100. package/esm/user.js +9 -6
  101. package/esm/user.js.map +1 -1
  102. package/esm/util-Bl2u6LpY.js +136 -0
  103. package/esm/util-Bl2u6LpY.js.map +1 -0
  104. package/esm/util.js +58 -14
  105. package/esm/util.js.map +1 -1
  106. package/esm/{version-wnf-TITV.js → version-BQAL8sQO.js} +2 -2
  107. package/esm/{version-wnf-TITV.js.map → version-BQAL8sQO.js.map} +1 -1
  108. package/esm/{version-BlsI7hX2.js → version-CA9Mdm3A.js} +16 -16
  109. package/esm/version-CA9Mdm3A.js.map +1 -0
  110. package/i18n/package.json +5 -0
  111. package/models/app/pages/VersionInfo/components/VersionInfo.d.ts +1 -1
  112. package/models/app/pages/VersionInfo/components/VersionInfo.styled.d.ts +1 -2
  113. package/models/i18n/index.d.ts +5 -0
  114. package/models/i18n/redux/sagas.d.ts +19 -0
  115. package/models/i18n/redux/selectors.d.ts +11 -0
  116. package/models/i18n/redux/slice.d.ts +198 -0
  117. package/models/i18n/routes.d.ts +8 -0
  118. package/models/i18n/useI18n.hook.d.ts +20 -0
  119. package/models/index.d.ts +1 -0
  120. package/models/models/AppState.d.ts +2 -0
  121. package/models/models/ContentTypeMapping.d.ts +6 -1
  122. package/models/models/EntryMapper.d.ts +2 -1
  123. package/models/models/Locales.d.ts +11 -0
  124. package/models/models/MatchedRoute.d.ts +5 -1
  125. package/models/models/RouteComponent.d.ts +0 -1
  126. package/models/models/RouteNode.d.ts +4 -2
  127. package/models/models/SSRContext.d.ts +4 -4
  128. package/models/models/StaticRoute.d.ts +12 -1
  129. package/models/models/WithEvents.d.ts +8 -0
  130. package/models/models/config/AppConfig.d.ts +2 -0
  131. package/models/models/config/I18n.d.ts +38 -0
  132. package/models/models/config/ServerConfig.d.ts +14 -0
  133. package/models/redux/index.d.ts +2 -1
  134. package/models/redux/sagas/index.d.ts +3 -1
  135. package/models/redux/sagas/injector.d.ts +13 -0
  136. package/models/redux/store/injectors/index.d.ts +26 -0
  137. package/models/redux/store/injectors/inject.d.ts +24 -0
  138. package/models/redux/store/injectors/util.d.ts +2 -0
  139. package/models/redux/store/store.d.ts +13 -4
  140. package/models/redux/util.d.ts +1 -1
  141. package/models/routing/components/RouteLoader.d.ts +3 -3
  142. package/models/routing/httpContext.d.ts +0 -1
  143. package/models/routing/index.d.ts +1 -0
  144. package/models/routing/redux/actions.d.ts +1 -1
  145. package/models/routing/redux/invokeSearch.d.ts +22 -0
  146. package/models/routing/redux/selectors.d.ts +47 -4
  147. package/models/routing/util/expressions.d.ts +1 -1
  148. package/models/routing/util/find-contenttype-mapping.d.ts +3 -1
  149. package/models/search/containers/withListing.d.ts +1 -1
  150. package/models/search/containers/withSearch.d.ts +1 -1
  151. package/models/search/models/Queries.d.ts +3 -5
  152. package/models/search/models/Search.d.ts +43 -13
  153. package/models/search/models/SearchActions.d.ts +61 -18
  154. package/models/search/models/SearchProps.d.ts +11 -10
  155. package/models/search/models/SearchState.d.ts +23 -2
  156. package/models/search/models/SearchUtil.d.ts +3 -3
  157. package/models/search/redux/getIn.d.ts +2 -2
  158. package/models/search/redux/reducers.d.ts +3 -4
  159. package/models/search/redux/sagas.d.ts +13 -14
  160. package/models/search/redux/schema.d.ts +3 -3
  161. package/models/search/redux/selectors.d.ts +64 -42
  162. package/models/search/redux/util.d.ts +10 -1
  163. package/models/search/search/ContensisDeliveryApi.d.ts +6 -26
  164. package/models/search/search/expressions.d.ts +6 -4
  165. package/models/search/search/util.d.ts +9 -7
  166. package/models/search/transformations/state-to-queryparams.mapper.d.ts +1 -1
  167. package/models/server/features/linkdepth-api/search.d.ts +1 -1
  168. package/models/server/features/response-handler/render-stream.d.ts +2 -4
  169. package/models/server/features/static-assets/index.d.ts +4 -3
  170. package/models/server/internalServer.d.ts +1 -2
  171. package/models/server/middleware/subsiteDebug.d.ts +11 -0
  172. package/models/server/root.d.ts +3 -0
  173. package/models/server/util/bundles.d.ts +9 -9
  174. package/models/server/util/jsx.d.ts +2 -14
  175. package/models/user/components.styled/Login.styled.d.ts +1 -1
  176. package/models/user/components.styled/LoginForm.styled.d.ts +1 -1
  177. package/models/user/hocs/withRegistration.d.ts +1 -1
  178. package/models/util/CachedDeliveryApi.d.ts +8 -2
  179. package/models/util/ContensisDeliveryApi.d.ts +2 -4
  180. package/models/util/NoSSR.d.ts +6 -0
  181. package/models/util/SSRContext.d.ts +3 -19
  182. package/models/util/donotuse_useHistory.d.ts +6 -0
  183. package/models/util/errors.d.ts +16 -0
  184. package/models/util/index.d.ts +7 -2
  185. package/models/util/subsite.d.ts +12 -0
  186. package/models/util/urls.d.ts +1 -2
  187. package/models/util/useIsClient.d.ts +6 -0
  188. package/package.json +37 -39
  189. package/cjs/App-vZrUfVgQ.js.map +0 -1
  190. package/cjs/ChangePassword.container-ECjEXixF.js.map +0 -1
  191. package/cjs/CookieHelper.class-C3Eqoze9.js.map +0 -1
  192. package/cjs/RouteLoader-D5Yg7EB5.js.map +0 -1
  193. package/cjs/SSRContext-DVj_QAC1.js.map +0 -1
  194. package/cjs/ToJs-C9jwV7YB.js.map +0 -1
  195. package/cjs/VersionInfo-B_dKCubg.js.map +0 -1
  196. package/cjs/sagas-BVX4Ps1e.js.map +0 -1
  197. package/cjs/selectors-wCs5fHD4.js.map +0 -1
  198. package/cjs/store-D07FOXvM.js.map +0 -1
  199. package/cjs/version-B7XFkBhY.js.map +0 -1
  200. package/esm/App-DLZweVSp.js.map +0 -1
  201. package/esm/ChangePassword.container-BgzIy8dA.js.map +0 -1
  202. package/esm/CookieHelper.class-FTURFpz3.js.map +0 -1
  203. package/esm/RouteLoader-xeQBXywk.js.map +0 -1
  204. package/esm/SSRContext-BE8ElZ3X.js.map +0 -1
  205. package/esm/ToJs-CNzfvyxJ.js.map +0 -1
  206. package/esm/VersionInfo-Cno7K0OA.js.map +0 -1
  207. package/esm/sagas-JI51CS37.js.map +0 -1
  208. package/esm/selectors-DO2ocdOp.js.map +0 -1
  209. package/esm/store-3u0RzHZ0.js.map +0 -1
  210. package/esm/version-BlsI7hX2.js.map +0 -1
  211. package/models/redux/store/injectors.d.ts +0 -31
  212. package/models/search/search/ToJs.d.ts +0 -4
@@ -1,23 +1,26 @@
1
- import { c as cachedSearch, S as SSRContextProvider, d as deliveryApi } from './SSRContext-BE8ElZ3X.js';
1
+ import { c as cachedSearch, d as deliveryApi } from './ContensisDeliveryApi-LWYXevZ1.js';
2
2
  import { Query as Query$1 } from 'contensis-delivery-api';
3
3
  import React from 'react';
4
4
  import { Provider } from 'react-redux';
5
+ import { a as actions } from './slice-C6JLQik8.js';
5
6
  import mapJson from 'jsonpath-mapper';
6
- import { a8 as defaultExpressions, a9 as termExpressions, aa as contentTypeIdExpression, ab as filterExpressions, ac as orderByExpression, ad as customWhereExpressions, ae as cloneDeep } from './sagas-JI51CS37.js';
7
+ import { a7 as defaultExpressions, a8 as termExpressions, a9 as contentTypeIdExpression, aa as filterExpressions, ab as orderByExpression, ac as customWhereExpressions, ad as cloneDeep } from './sagas-Fr9yRduO.js';
7
8
  import 'reselect';
8
9
  import 'immer';
9
10
  import 'deep-equal';
10
11
  import 'deepmerge';
11
12
  import 'query-string';
12
13
  import { Op, Query } from 'contensis-core-api';
13
- import { s as setCachingHeaders, u as url } from './VersionInfo-Cno7K0OA.js';
14
+ import { s as setCachingHeaders, u as urls } from './urls-tLxo_skx.js';
14
15
  import 'isomorphic-fetch';
15
16
  import express from 'express';
16
17
  import http from 'http';
17
18
  import httpProxy from 'http-proxy';
19
+ import { s as shorten, c as createLocaleRoutes, h as history, p as pickProject, r as rootSaga } from './App-Bvs7Km54.js';
20
+ export { A as ReactApp } from './App-Bvs7Km54.js';
18
21
  import fs from 'fs';
19
22
  import path from 'path';
20
- import { path as path$1 } from 'app-root-path';
23
+ import appRootPath from 'app-root-path';
21
24
  import { renderToPipeableStream, renderToString } from 'react-dom/server';
22
25
  import { matchRoutes } from 'react-router-dom';
23
26
  import { Helmet } from 'react-helmet';
@@ -25,32 +28,38 @@ import { ServerStyleSheet } from 'styled-components';
25
28
  import serialize from 'serialize-javascript';
26
29
  import { noop, identity } from 'lodash';
27
30
  import { buildCleaner } from 'lodash-clean';
28
- import { a as Cookies } from './CookieHelper.class-FTURFpz3.js';
31
+ import { a as Cookies } from './CookieHelper.class-C6rTRl_1.js';
29
32
  import cookiesMiddleware from 'universal-cookie-express';
30
- import { c as createStore } from './store-3u0RzHZ0.js';
31
- import { h as history, p as pickProject, r as rootSaga } from './App-DLZweVSp.js';
32
- export { A as ReactApp } from './App-DLZweVSp.js';
33
- import { s as setVersionStatus, d as setVersion } from './version-BlsI7hX2.js';
34
- import { a3 as selectSurrogateKeys, a4 as selectSsrApiCalls, h as selectRouteEntry, n as selectCurrentProject, g as getImmutableOrJS, d as setCurrentProject, K as selectCurrentSearch } from './selectors-DO2ocdOp.js';
35
- import { H as HttpContext, m as mergeStaticRoutes } from './RouteLoader-xeQBXywk.js';
33
+ import { c as createStore } from './store-B4IrBYHm.js';
34
+ import { s as setVersionStatus, c as setVersion } from './version-CA9Mdm3A.js';
35
+ import { a6 as selectSurrogateKeys, a7 as selectSsrApiCalls, j as selectRouteEntry, f as selectCurrentProject, g as getImmutableOrJS, s as setCurrentProject, F as selectCurrentSearch } from './selectors-8ROQrTd7.js';
36
+ import { H as HttpContext, m as mergeStaticRoutes } from './RouteLoader-CzrlySZf.js';
36
37
  import { Transform } from 'stream';
37
38
  import { ChunkExtractor, ChunkExtractorManager } from '@loadable/server';
38
39
  import chalk from 'chalk';
39
40
  import minifyCssString from 'minify-css-string';
40
41
  import { CookiesProvider } from 'react-cookie';
42
+ import { HelmetProvider } from 'react-helmet-async';
41
43
  import { StaticRouter } from 'react-router-dom/server';
44
+ import { S as SSRContextProvider, g as getSubsitePath } from './SSRContext-Bxtg1KGv.js';
45
+ import './VersionInfo-By2ZCZOh.js';
46
+ import './CookieConstants-DEmbwzYr.js';
47
+ import '@reduxjs/toolkit';
42
48
  import 'loglevel';
43
49
  import '@redux-saga/core/effects';
50
+ import './version-BQAL8sQO.js';
51
+ import './util-Bl2u6LpY.js';
52
+ import './selectors-DcmvOeX2.js';
44
53
  import './_commonjsHelpers-BFTU3MAI.js';
45
- import './version-wnf-TITV.js';
54
+ import 'history';
55
+ import 'await-to-js';
56
+ import 'redux-saga';
57
+ import './ChangePassword.container-CUBtn82K.js';
58
+ import './matchGroups-_w8BwzCC.js';
59
+ import './ToJs-BnRRHk6f.js';
46
60
  import 'redux';
47
61
  import 'redux-thunk';
48
- import 'redux-saga';
49
62
  import 'redux-injectors-19';
50
- import 'history';
51
- import 'await-to-js';
52
- import './ChangePassword.container-BgzIy8dA.js';
53
- import './ToJs-CNzfvyxJ.js';
54
63
 
55
64
  /**
56
65
  * Util class holds our search results helper boilerplate methods
@@ -610,42 +619,66 @@ const makeLinkDepthMiddleware = ({
610
619
  }
611
620
  };
612
621
 
622
+ /**
623
+ * Development proxy for Subsite PoC
624
+ * Catch all routes before they hit CRB handlers
625
+ * and rewrite them to include the subsite base path,
626
+ * this allows us to run the subsite in a subfolder in development
627
+ * In production we will handle this with a path rewrite in the Cloud Dashboard site configuration,
628
+ * @param subsitePath the content base path we will rewrite to
629
+ * @param exceptions an array of path prefixes to ignore when rewriting, useful for ignoring assets that do not live in the subsite base path
630
+ */
631
+ const subsiteDebugMiddleware = (subsitePath, exceptions = []) => (req, res, next) => {
632
+ if (!subsitePath || req.hostname !== 'localhost' || req.path.startsWith('/api/') || exceptions.some(exception => req.path.startsWith(exception))) return next();
633
+ if (!req.path.startsWith(`${subsitePath}/`)) {
634
+ console.warn(`[subsite-debug-middleware] Rewriting (${subsitePath})${req.url}`);
635
+ if (req.path === '/' || req.path === subsitePath) req.url = subsitePath;else req.url = `${subsitePath}${req.url}`;
636
+ res.setHeader('x-crb-subsite-content-path', req.url);
637
+
638
+ // Important to set the subsite_path header as this drives the subsite-scoped routing logic
639
+ req.headers['subsite_path'] = subsitePath;
640
+ }
641
+ next();
642
+ };
643
+
613
644
  const servers$1 = SERVERS; /* global SERVERS */
614
645
  const project = PROJECT; /* global PROJECT */
615
646
  const alias$1 = ALIAS; /* global ALIAS */
616
- const deliveryApiHostname = url(alias$1, project).api;
647
+ const deliveryApiHostname = urls(alias$1, project).api;
648
+ const proxyTimeoutMs = 45_000;
617
649
  const assetProxy = httpProxy.createProxyServer();
618
650
  const deliveryProxy = httpProxy.createProxyServer();
619
651
  const reverseProxies = (app, reverseProxyPaths = []) => {
620
652
  deliveryApiProxy(deliveryProxy, app);
621
- app.all(reverseProxyPaths, (req, res) => {
622
- const target = req.hostname.indexOf('preview-') || req.hostname.indexOf('preview.') || req.hostname === 'localhost' ? servers$1.previewIis || servers$1.iis : servers$1.iis;
653
+ app.all(reverseProxyPaths.map(proxyPath =>
654
+ // Patch to update paths for express v5
655
+ proxyPath.endsWith('/*') ? `${proxyPath.slice(0, -2)}/{*splat}` : proxyPath.endsWith('/**') ? `${proxyPath.slice(0, -3)}/{*splat}` : proxyPath), (req, res) => {
656
+ const target = req.hostname.includes('preview-') || req.hostname.includes('preview.') || req.hostname === 'localhost' ? servers$1.previewIis || servers$1.iis : servers$1.iis;
623
657
  assetProxy.web(req, res, {
624
658
  target,
625
- changeOrigin: true
626
- });
627
- assetProxy.on('error', e => {
628
- /* eslint-disable no-console */
629
- console.log(`Proxy Request for ${req.path} HostName:${req.hostname} failed with ${e}`);
630
- /* eslint-enable no-console */
659
+ changeOrigin: true,
660
+ proxyTimeout: proxyTimeoutMs,
661
+ timeout: proxyTimeoutMs
631
662
  });
632
663
  });
664
+ assetProxy.on('error', (e, req) => {
665
+ console.log(`[assetProxy] "${req.method} ${req.url}" host: ${req.headers.host} failed with ${e}`);
666
+ });
633
667
  };
634
668
  const deliveryApiProxy = (apiProxy, app) => {
635
669
  // This is just here to stop cors requests on localhost. In Production this is mapped using varnish.
636
- app.all(['/api/delivery/*', '/api/forms/*', '/api/image/*', '/authenticate/*'], (req, res) => {
637
- /* eslint-disable no-console */
638
- console.log(`Proxying api request to ${servers$1.alias}`);
670
+ app.all(['/api/delivery/{*splat}', '/api/forms/{*splat}', '/api/image/{*splat}', '/authenticate/{*splat}'], (req, res) => {
671
+ console.log(`[apiProxy] "${req.method} ${shorten(req.url)}" target: ${servers$1.alias}`);
639
672
  apiProxy.web(req, res, {
640
673
  target: deliveryApiHostname,
641
- changeOrigin: true
642
- });
643
- apiProxy.on('error', e => {
644
- /* eslint-disable no-console */
645
- console.log(`Proxy request for ${req.path} HostName:${req.hostname} failed with ${e}`);
646
- /* eslint-enable no-console */
674
+ changeOrigin: true,
675
+ proxyTimeout: proxyTimeoutMs,
676
+ timeout: proxyTimeoutMs
647
677
  });
648
678
  });
679
+ apiProxy.on('error', (e, req) => {
680
+ console.log(`[apiProxy] "${req.method} ${req.url}" host: ${req.headers.host} failed with ${e}`);
681
+ });
649
682
  };
650
683
 
651
684
  const CacheDuration = {
@@ -720,9 +753,8 @@ const resolveStartupMiddleware = ({
720
753
  if (maxage) res.set('Cache-Control', `public, max-age=${maxage}`);
721
754
  res.sendFile(startupFileLocation);
722
755
  } catch (sendFileError) {
723
- // eslint-disable-next-line no-console
724
756
  console.log(`Unable to send file startup.js at '${startupFileLocation}'`, sendFileError);
725
- next();
757
+ res.status(404).send();
726
758
  }
727
759
  } else {
728
760
  next();
@@ -730,8 +762,11 @@ const resolveStartupMiddleware = ({
730
762
  };
731
763
 
732
764
  // Serving static assets
765
+ const {
766
+ path: appPath
767
+ } = appRootPath;
733
768
  const staticAssets = (app, {
734
- appRootPath = path$1,
769
+ appRootPath = appPath,
735
770
  scripts = {},
736
771
  startupScriptFilename = 'startup.js',
737
772
  staticFolderPath = 'static',
@@ -750,9 +785,7 @@ const staticAssets = (app, {
750
785
  maxage: CacheDuration.static,
751
786
  startupScriptFilename: scripts.startup || startupScriptFilename,
752
787
  staticFolderPath
753
- }),
754
- // eslint-disable-next-line import/no-named-as-default-member
755
- express.static(`dist/${staticFolderPath}`, {
788
+ }), express.static(`dist/${staticFolderPath}`, {
756
789
  // these maxage values are different in config but the same in runtime,
757
790
  // this one is somehow converted and should end up being the same as CacheDuration.static
758
791
  maxAge: CacheDuration.expressStatic
@@ -802,7 +835,31 @@ const handleResponse = (request, response, content, send = 'send') => {
802
835
  * @param response the express Response object
803
836
  * @param stream all chunks are piped to this stream to add additional style elements to each streamed chunk
804
837
  */
805
- const renderStream = (getContextHtml, jsx, response, stream) => {
838
+ const renderStream = (getContextHtml, jsx, request, response, stream) => {
839
+ // Store timeout reference for cleanup on normal or abnormal termination
840
+ let timeoutId = null;
841
+ const disposeTimeout = () => {
842
+ if (timeoutId) {
843
+ clearTimeout(timeoutId);
844
+ timeoutId = null;
845
+ }
846
+ };
847
+
848
+ // Only used for abnormal termination
849
+ const abortCleanup = err => {
850
+ disposeTimeout();
851
+ stream.destroy(err instanceof Error ? err : undefined);
852
+ abort();
853
+ };
854
+
855
+ // Guard against client disconnect
856
+ request.on('close', () => abortCleanup());
857
+
858
+ // Guard against transform errors
859
+ stream.on('error', err => {
860
+ abortCleanup(err);
861
+ if (!response.headersSent) response.destroy(err);
862
+ });
806
863
  const {
807
864
  abort,
808
865
  pipe
@@ -811,7 +868,7 @@ const renderStream = (getContextHtml, jsx, response, stream) => {
811
868
  const html = getContextHtml(false);
812
869
  if (!html) {
813
870
  // this means we have finished with the response already
814
- abort();
871
+ abortCleanup();
815
872
  } else {
816
873
  const header = html.split('{{APP}}')[0];
817
874
  response.setHeader('content-type', 'text/html; charset=utf-8');
@@ -822,11 +879,15 @@ const renderStream = (getContextHtml, jsx, response, stream) => {
822
879
  onAllReady() {
823
880
  const footer = getContextHtml(true).split('{{APP}}')[1];
824
881
  stream.write(footer);
882
+ disposeTimeout(); // Clear the timeout, let stream end naturally
825
883
  },
826
884
  onShellError(error) {
827
- response.statusCode = 500;
828
- response.setHeader('content-type', 'text/html; charset=utf-8');
829
- response.send('<h1>Something went wrong</h1>');
885
+ abortCleanup(error); // Abnormal - destroy everything
886
+ if (!response.headersSent) {
887
+ response.statusCode = 500;
888
+ response.setHeader('content-type', 'text/html; charset=utf-8');
889
+ response.send('<h1>Something went wrong</h1>');
890
+ }
830
891
  console.error(`[renderToPipeableStream:onShellError]`, error);
831
892
  },
832
893
  onError(error) {
@@ -834,10 +895,13 @@ const renderStream = (getContextHtml, jsx, response, stream) => {
834
895
  }
835
896
  });
836
897
 
837
- // Abandon and switch to client rendering if enough time passes.
898
+ // Abandon and switch to client rendering after 30s.
838
899
  // Try lowering this to see the client recover.
839
- setTimeout(() => abort(), 30 * 1000);
840
- stream === null || stream === void 0 || stream.pipe(response);
900
+ timeoutId = setTimeout(() => {
901
+ timeoutId = null;
902
+ abortCleanup();
903
+ }, 30_000);
904
+ stream.pipe(response);
841
905
  };
842
906
 
843
907
  /**
@@ -877,6 +941,23 @@ const styledComponentsStream = sheet => {
877
941
  this.push(styledCSS + renderedHtml);
878
942
  }
879
943
  callback();
944
+ },
945
+ destroy(err, callback) {
946
+ // Called on both stream.destroy() and natural end
947
+ // Stops the sheet intercepting styles & releases its references
948
+
949
+ // try/catch is required if sheet.seal() throws for any reason,
950
+ // callback(err) must still be called, as Node.js stream internals depend
951
+ // on it to complete teardown. Omitting it causes the stream to hang.
952
+ try {
953
+ sheet.seal();
954
+ } catch (sealErr) {
955
+ // Catch any errors from sealing the sheet, we MUST always call the
956
+ // callback to prevent hanging the stream
957
+
958
+ console.error('[styledComponentsStream] sheet.seal() failed - styles may leak:', sealErr);
959
+ }
960
+ callback(err);
880
961
  }
881
962
  });
882
963
  return readerWriter;
@@ -1038,6 +1119,7 @@ const unhandledExceptionHandler = (handleExceptions = handleDefaultEvents) => {
1038
1119
  }
1039
1120
  };
1040
1121
 
1122
+ const logPrefix = '[addHeaders]';
1041
1123
  const addStandardHeaders = (state, response, packagejson, groups) => {
1042
1124
  if (state) {
1043
1125
  try {
@@ -1051,14 +1133,14 @@ const addStandardHeaders = (state, response, packagejson, groups) => {
1051
1133
  // - add `any-update` header that will indiscriminately
1052
1134
  // invalidate the SSR page cache when any content is updated
1053
1135
  const addAnyUpdateHeader = routingSurrogateKeys.length >= 2000 || response.statusCode >= 400 || anyApiError;
1054
- console.info(`[addStandardHeaders] ${addAnyUpdateHeader ? anyUpdateHeader : routingSurrogateKeys.length} surrogate keys for ${response.req.url}`);
1136
+ console.info(`${logPrefix} ${addAnyUpdateHeader ? anyUpdateHeader : routingSurrogateKeys.length} surrogate keys for ${response.req.url}`);
1055
1137
  const surrogateKeys = addAnyUpdateHeader ? anyUpdateHeader : routingSurrogateKeys.join(' ');
1056
1138
  const surrogateKeyHeader = `${packagejson.name}-app ${surrogateKeys}`;
1057
1139
  response.setHeader('surrogate-key', surrogateKeyHeader);
1058
1140
  addVarnishAuthenticationHeaders(state, response, groups);
1059
1141
  response.setHeader('surrogate-control', `max-age=${getCacheDuration(response.statusCode)}`);
1060
1142
  } catch (e) {
1061
- console.info('[addStandardHeaders] Error adding headers', e.message);
1143
+ console.info(`${logPrefix} Error adding headers`, e.message);
1062
1144
  }
1063
1145
  }
1064
1146
  };
@@ -1071,14 +1153,13 @@ const addVarnishAuthenticationHeaders = (state, response, groups = {}) => {
1071
1153
  globalGroups,
1072
1154
  allowedGroups
1073
1155
  } = groups;
1074
- // console.info(globalGroups, allowedGroups);
1075
1156
  let allGroups = Array.from(globalGroups && globalGroups[project] || {});
1076
1157
  if (stateEntry && getImmutableOrJS(stateEntry, ['authentication', 'isLoginRequired']) && allowedGroups && allowedGroups[project]) {
1077
1158
  allGroups = [...allGroups, ...allowedGroups[project]];
1078
1159
  }
1079
1160
  response.header('x-contensis-viewer-groups', allGroups.join('|'));
1080
1161
  } catch (e) {
1081
- console.info('Error adding authentication header', e);
1162
+ console.info(`${logPrefix} Error adding authentication header`, e);
1082
1163
  }
1083
1164
  }
1084
1165
  };
@@ -1155,13 +1236,15 @@ const replaceHtml = ({
1155
1236
  */
1156
1237
  const ssrJsxProducer = (ReactApp, {
1157
1238
  providers,
1158
- props,
1159
- ssrAssets
1239
+ props
1240
+ // ssrAssets,
1160
1241
  }) => {
1161
1242
  var _providers$styledComp;
1162
1243
  // Recast ChunkExtractorManager to avoid TS error `Property 'children' does not exist on type...`
1163
1244
  const ChunkExtractor = ChunkExtractorManager;
1164
- const jsx = /*#__PURE__*/React.createElement(ChunkExtractor, {
1245
+ const jsx = /*#__PURE__*/React.createElement(HelmetProvider, {
1246
+ context: providers.helmet
1247
+ }, /*#__PURE__*/React.createElement(ChunkExtractor, {
1165
1248
  extractor: providers.loadable.extractor
1166
1249
  }, /*#__PURE__*/React.createElement(CookiesProvider, {
1167
1250
  cookies: providers.cookies
@@ -1170,16 +1253,20 @@ const ssrJsxProducer = (ReactApp, {
1170
1253
  }, /*#__PURE__*/React.createElement(HttpContext.Provider, {
1171
1254
  value: providers.httpContext
1172
1255
  }, /*#__PURE__*/React.createElement(StaticRouter, {
1173
- location: providers.router.url
1256
+ location: providers.router.url,
1257
+ future: {
1258
+ v7_startTransition: true,
1259
+ v7_relativeSplatPath: true
1260
+ }
1174
1261
  }, /*#__PURE__*/React.createElement(SSRContextProvider, {
1175
1262
  accessMethod: providers.ssrContext.accessMethod,
1176
1263
  request: providers.ssrContext.request,
1177
- response: providers.ssrContext.response,
1178
- ssrAssets: ssrAssets
1264
+ response: providers.ssrContext.response
1265
+ // ssrAssets={ssrAssets}
1179
1266
  }, /*#__PURE__*/React.createElement(ReactApp, {
1180
1267
  routes: props.routes,
1181
1268
  withEvents: props.withEvents
1182
- })))))));
1269
+ }))))))));
1183
1270
 
1184
1271
  // Wrap the JSX in a StyleSheetManager if a ServerStyleSheet is provided
1185
1272
  return !((_providers$styledComp = providers.styledComponents) !== null && _providers$styledComp !== void 0 && _providers$styledComp.sheet) ? jsx : providers.styledComponents.sheet.collectStyles(jsx);
@@ -1201,8 +1288,12 @@ const webApp = (app, ReactApp, config) => {
1201
1288
  disableSsrRedux,
1202
1289
  enableSsrCookies,
1203
1290
  handleResponses,
1204
- handleExceptions = true
1291
+ handleExceptions = true,
1292
+ i18n
1205
1293
  } = config;
1294
+
1295
+ // process locales in static routes for i18n
1296
+ const localeRoutes = createLocaleRoutes(routes);
1206
1297
  const staticRoutePath = config.staticRoutePath || staticFolderPath;
1207
1298
  let isRenderingJsxToString = config.renderToString || false;
1208
1299
  const bundleData = getBundleData(config, staticRoutePath);
@@ -1216,8 +1307,16 @@ const webApp = (app, ReactApp, config) => {
1216
1307
  if (handleExceptions !== false) unhandledExceptionHandler(handleExceptions); // Create `process.on` event handlers for unhandled exceptions (Node v15+)
1217
1308
 
1218
1309
  const versionInfo = getVersionInfo(staticFolderPath);
1219
- app.get('/*', cookiesMiddleware(), async (request, response) => {
1220
- const url = encodeURI(request.url);
1310
+ app.get('/{*splat}', cookiesMiddleware(), async (request, response) => {
1311
+ /*
1312
+ * Do not inject url directly into HTML as it can lead to XSS attacks
1313
+ * CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
1314
+ * CWE-96: Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)
1315
+ * Removed URL encoding as it causes inconsistencies when routes contain encoded characters in SSR
1316
+ * e.g. /search?category=sport%20and%20wellbeing becomes /search?category=sport%2520and%2520wellbeing
1317
+ * // const url = encodeURI(request.url);
1318
+ */
1319
+ const url = request.url;
1221
1320
  const matchedStaticRoute = matchRoutes(routes.StaticRoutes, request.path);
1222
1321
  const isStaticRoute = matchedStaticRoute && matchedStaticRoute.length > 0;
1223
1322
  if (isStaticRoute) {
@@ -1257,25 +1356,22 @@ const webApp = (app, ReactApp, config) => {
1257
1356
  // In server-side blocks world, the hostname requested by the client resides in the x-orig-host header
1258
1357
  // Because of this, we prioritize x-orig-host when setting our hostname
1259
1358
  const hostname = request.headers['x-orig-host'] || request.hostname;
1260
- console.info(`Request for ${request.path} hostname: ${hostname} versionStatus: ${versionStatus}`);
1359
+ const subsitePath = getSubsitePath(request);
1360
+ const subsitePathScript = subsitePath ? `window.subsitePath = ${serialize(subsitePath)};` : '';
1361
+ console.info(`[webApp] "${request.method} ${request.path}" hostname: ${hostname} versionStatus: ${versionStatus}`);
1261
1362
  store.dispatch(setVersionStatus(versionStatus));
1262
1363
  store.dispatch(setVersion(versionInfo.commitRef, versionInfo.buildNo));
1263
1364
  const project = pickProject(hostname, request.query);
1264
1365
  const groups = allowedGroups && allowedGroups[project];
1265
1366
  store.dispatch(setCurrentProject(project, groups, hostname));
1367
+ if (i18n) {
1368
+ store.dispatch(actions.INIT_LOCALES({
1369
+ locales: {},
1370
+ routes: localeRoutes,
1371
+ ...i18n
1372
+ }));
1373
+ }
1266
1374
  const loadableExtractor = loadableChunkExtractors();
1267
-
1268
- // type ChunkExtractorManagerPropsForReact18 = ChunkExtractorManagerProps & {
1269
- // children?: React.ReactNode;
1270
- // };
1271
-
1272
- // // Recast ChunkExtractorManager to avoid TS error `Property 'children' does not exist on type...`
1273
- // const ChunkExtractor = ChunkExtractorManager as ClassType<
1274
- // ChunkExtractorManagerPropsForReact18,
1275
- // Component<ChunkExtractorManagerPropsForReact18>,
1276
- // ComponentClass<ChunkExtractorManagerPropsForReact18>
1277
- // >;
1278
-
1279
1375
  const ssrCookies = enableSsrCookies ?
1280
1376
  // these cookies are managed by the cookiesMiddleware and contain listeners
1281
1377
  // when cookies are read or written in ssr can be added to the `set-cookie` response header
@@ -1290,12 +1386,17 @@ const webApp = (app, ReactApp, config) => {
1290
1386
  // and read back any context props set by the ReactApp
1291
1387
  const context = {};
1292
1388
 
1389
+ // Per-request helmet context object — populated by HelmetProvider during renderToString
1390
+ // Using a fresh object per request ensures thread safety under concurrent SSR requests
1391
+ const helmetContext = {};
1392
+
1293
1393
  // Amalgamate all props for the various Providers we wrap the ReactApp with
1294
1394
  const jsxProviderProps = {
1295
1395
  loadable: {
1296
1396
  extractor: loadableExtractor.commonLoadableExtractor
1297
1397
  },
1298
1398
  cookies: ssrCookies,
1399
+ helmet: helmetContext,
1299
1400
  redux: store,
1300
1401
  httpContext: context,
1301
1402
  router: {
@@ -1325,13 +1426,10 @@ const webApp = (app, ReactApp, config) => {
1325
1426
  // Dynamic doesn't need sagas
1326
1427
  // or styles, or any split component bundles
1327
1428
  // nor are we streaming responses
1328
- const isDynamicHints = `<script ${attributes}>window.versionStatus = "${versionStatus}"; window.isDynamic = true;</script>`;
1429
+ const isDynamicHints = `<script ${attributes}>window.isDynamic = true; ${subsitePathScript}</script>`;
1329
1430
  const jsx = ssrJsxProducer(ReactApp, {
1330
1431
  providers: jsxProviderProps,
1331
- props: jsxReactAppProps,
1332
- ssrAssets: {
1333
- serializedState: isDynamicHints
1334
- }
1432
+ props: jsxReactAppProps
1335
1433
  });
1336
1434
  renderToString(jsx);
1337
1435
 
@@ -1390,10 +1488,7 @@ const webApp = (app, ReactApp, config) => {
1390
1488
  return true;
1391
1489
  }
1392
1490
  if (!disableSsrRedux) {
1393
- // window.versionStatus is not strictly required here and is added to support cases
1394
- // where a consumer may not be using the contensisVersionStatus in redux and calling
1395
- // the `getClientSideVersionStatus()` method directly
1396
- serialisedReduxData = `<script ${attributes}>window.versionStatus = "${versionStatus}"; window.REDUX_DATA = ${serialisedReduxData}</script>`;
1491
+ serialisedReduxData = `<script ${attributes}>${subsitePathScript} window.__USE_HYDRATE__ = true; window.REDUX_DATA = ${serialisedReduxData}</script>`;
1397
1492
  }
1398
1493
  }
1399
1494
 
@@ -1402,22 +1497,6 @@ const webApp = (app, ReactApp, config) => {
1402
1497
  allowedGroups,
1403
1498
  globalGroups
1404
1499
  });
1405
-
1406
- // // Produce the ssr jsx one time so we can get any style tags to pass back in
1407
- // ssrJsxProducer(ReactApp, {
1408
- // providers: { ...jsxProviderProps, styledComponents: { sheet } },
1409
- // props: jsxReactAppProps,
1410
- // });
1411
-
1412
- // // After running rootSaga (and rendering subsquent children)
1413
- // // there should be additional react-loadable
1414
- // // code-split bundles for any page components as well as core app bundles
1415
- // const bundleTags = getBundleTags(
1416
- // loadableExtractor,
1417
- // scripts,
1418
- // staticRoutePath
1419
- // );
1420
-
1421
1500
  const sheet = new ServerStyleSheet();
1422
1501
  const styledJsx = ssrJsxProducer(ReactApp, {
1423
1502
  providers: {
@@ -1426,13 +1505,7 @@ const webApp = (app, ReactApp, config) => {
1426
1505
  sheet
1427
1506
  }
1428
1507
  },
1429
- props: jsxReactAppProps,
1430
- ssrAssets: {
1431
- // bundleTags,
1432
- // htmlAttributes,
1433
- // metadata,
1434
- // title,
1435
- }
1508
+ props: jsxReactAppProps
1436
1509
  });
1437
1510
 
1438
1511
  // We have to call renderToString() in order for all components to have
@@ -1440,15 +1513,23 @@ const webApp = (app, ReactApp, config) => {
1440
1513
  const html = renderToString(styledJsx);
1441
1514
  // Helmet.renderStatic() has to be called synchronously immediately after calling renderToString()
1442
1515
  // as it is not thread-safe (or specifically scoped to only this request)
1516
+ // TODO: deprecate `react-helmet`
1443
1517
  const helmet = Helmet.renderStatic();
1444
1518
 
1519
+ // helmetContext is populated synchronously by HelmetProvider during renderToString()
1520
+ // It is scoped per-request via the helmetContext object, making this thread-safe
1521
+ // under concurrent SSR requests (unlike the previous Helmet.renderStatic() global singleton)
1522
+ const {
1523
+ helmet: helmetAsync
1524
+ } = helmetContext;
1525
+
1445
1526
  // Because we have had to call renderToString() here to reliably gather all helmet metadata
1446
1527
  // We could potentially call sheet.getStyleTags() here too and avoid piping a react-rendered
1447
1528
  // stream to a second stream to inject styled-components CSS
1448
1529
 
1449
- const htmlAttributes = helmet.htmlAttributes.toString();
1450
- let title = helmet.title.toString();
1451
- const metadata = helmet.meta.toString().concat(helmet.base.toString()).concat(helmet.link.toString()).concat(helmet.script.toString()).concat(helmet.noscript.toString());
1530
+ const htmlAttributes = helmetAsync.htmlAttributes.toString() || helmet.htmlAttributes.toString();
1531
+ let title = helmet.title.toString().includes('><') ? helmetAsync.title.toString() : helmet.title.toString();
1532
+ const metadata = helmetAsync.meta.toString().concat(helmetAsync.base.toString()).concat(helmetAsync.priority.toString()).concat(helmetAsync.link.toString()).concat(helmetAsync.script.toString()).concat(helmetAsync.noscript.toString()).concat(helmet.meta.toString()).concat(helmet.base.toString()).concat(helmet.link.toString()).concat(helmet.script.toString()).concat(helmet.noscript.toString());
1452
1533
  try {
1453
1534
  /**
1454
1535
  * Loads all page assets into the provided templateHTML
@@ -1460,6 +1541,7 @@ const webApp = (app, ReactApp, config) => {
1460
1541
  * if the context has requested a redirect
1461
1542
  * */
1462
1543
  const getContextHtml = (isFinal = false, styleTags, renderedJsxMarkup) => {
1544
+ var _loadableExtractor$mo;
1463
1545
  if (context.url) {
1464
1546
  response.redirect(context.statusCode || 302, context.url);
1465
1547
  return '';
@@ -1474,13 +1556,18 @@ const webApp = (app, ReactApp, config) => {
1474
1556
  // Set response.status from React StaticRouter
1475
1557
  if (typeof context.statusCode === 'number') response.status(context.statusCode);
1476
1558
  const bundleTags = isFinal ? getBundleTags(loadableExtractor, scripts, staticRoutePath) : '';
1559
+
1560
+ // Getting style tags generated by "CSS Modules" because they will be
1561
+ // available to loadable stats if we have built parts of the app with CSS
1562
+ // plugins that are not within styled-components
1563
+ const styles = loadableExtractor === null || loadableExtractor === void 0 || (_loadableExtractor$mo = loadableExtractor.modern) === null || _loadableExtractor$mo === void 0 ? void 0 : _loadableExtractor$mo.getStyleTags();
1477
1564
  const html = replaceHtml({
1478
1565
  bundleTags,
1479
1566
  html: renderedJsxMarkup,
1480
1567
  htmlAttributes,
1481
1568
  metadata,
1482
1569
  state: serialisedReduxData,
1483
- styleTags,
1570
+ styleTags: `${styleTags || ''}${styles || ''}`,
1484
1571
  title,
1485
1572
  templateHTML,
1486
1573
  templateHTMLFragment,
@@ -1496,7 +1583,7 @@ const webApp = (app, ReactApp, config) => {
1496
1583
  const responseHTML = getContextHtml(true, styleTags, html);
1497
1584
  responseHandler(request, response, responseHTML);
1498
1585
  } else {
1499
- renderStream(getContextHtml, styledJsx, response, styledComponentsStream(sheet));
1586
+ renderStream(getContextHtml, styledJsx, request, response, styledComponentsStream(sheet));
1500
1587
  }
1501
1588
  } catch (err) {
1502
1589
  console.info(err.message);
@@ -1558,5 +1645,5 @@ var internalServer = {
1558
1645
  start
1559
1646
  };
1560
1647
 
1561
- export { internalServer as default, makeLinkDepthApi as linkDepthApi };
1648
+ export { subsiteDebugMiddleware as DO_NOT_COMMIT_subsiteDebugMiddleware, internalServer as default, makeLinkDepthApi as linkDepthApi };
1562
1649
  //# sourceMappingURL=contensis-react-base.js.map