@zengenti/contensis-react-base 3.0.1-beta.9 → 3.0.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/README.md CHANGED
@@ -126,6 +126,27 @@ https://www.conventionalcommits.org/en/v1.0.0/#summary
126
126
 
127
127
  # Changelog
128
128
 
129
+ #### 3.0.1 (2023-01-27)
130
+
131
+ ##### Bug Fixes
132
+
133
+ - search package update supporting 'fuzzy' search (67bf14f3)
134
+ - revert package `chalk@4` as v5 requires total ESM environment which is incompatible with the Node.js app server today (4dcd478d)
135
+ - node process terminating on unhandled exception / promise rejection when running on node.js 15+, implement default behaviour as in <15 with the option to turn this off. Export express `server` for package consumers who need to access server methods in app handlers (677cd00a)
136
+ - search package null errors when replacing entire search state with a fresh config, remove redundant nav code (b74a526b)
137
+ - state-to-searchuri - fix crash when app state is immutable (f4e265eb)
138
+ - search package issue with APPLY_CONFIG after immer conversion (a827d075)
139
+ - Update from Search Package to use ?pageIndex over /pageIndex by default (99e42b90)
140
+ - search package fix resolving customApi response in ssr causes thread to hang (c4bed5e8)
141
+ - always use `api-` uri for delivery api proxy requests (6887e440)
142
+ - useMinilist hook, handle undefined arguments. (12d906d7)
143
+ - ContensisDeliveryApi.js -Add null check in LruCache.remove method (95cb63bf)
144
+
145
+ ##### Refactors
146
+
147
+ - convert some files to typescript (5c3b74e2)
148
+ - Split deliveryApi and asset proxy servers into separate instances (7ae1e007)
149
+
129
150
  #### 3.0.0 (2022-10-06)
130
151
 
131
152
  ##### New Features
@@ -6,7 +6,7 @@ var App = require('./App-ee485b92.js');
6
6
  var contensisDeliveryApi = require('contensis-delivery-api');
7
7
  var React = require('react');
8
8
  var reactRedux = require('react-redux');
9
- var sagas = require('./sagas-03b7a270.js');
9
+ var sagas = require('./sagas-7c19ce8e.js');
10
10
  var mapJson = require('jsonpath-mapper');
11
11
  require('reselect');
12
12
  require('deepmerge');
@@ -17,24 +17,26 @@ var contensisCoreApi = require('contensis-core-api');
17
17
  var urls = require('./urls-6fcaf4c6.js');
18
18
  require('isomorphic-fetch');
19
19
  var express = require('express');
20
+ var http = require('http');
20
21
  var httpProxy = require('http-proxy');
21
22
  var fs = require('fs');
22
23
  var path = require('path');
23
24
  var appRootPath = require('app-root-path');
24
- var server$1 = require('react-dom/server');
25
+ var server$2 = require('react-dom/server');
25
26
  var reactRouterDom = require('react-router-dom');
26
27
  var reactRouterConfig = require('react-router-config');
27
28
  var reactHelmet = require('react-helmet');
28
29
  var styled = require('styled-components');
29
30
  var serialize$1 = require('serialize-javascript');
30
31
  var minifyCssString = require('minify-css-string');
31
- var server = require('@loadable/server');
32
+ var server$1 = require('@loadable/server');
32
33
  var lodash = require('lodash');
33
34
  var lodashClean = require('lodash-clean');
34
35
  var reactCookie = require('react-cookie');
35
36
  var version = require('./version-78dfc3bd.js');
36
37
  var actions = require('./actions-8dc9e8de.js');
37
38
  var selectors = require('./selectors-656da4b7.js');
39
+ var chalk = require('chalk');
38
40
  require('history');
39
41
  require('@redux-saga/core/effects');
40
42
  require('loglevel');
@@ -61,6 +63,7 @@ var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
61
63
  var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
62
64
  var serialize__default = /*#__PURE__*/_interopDefaultLegacy(serialize$1);
63
65
  var minifyCssString__default = /*#__PURE__*/_interopDefaultLegacy(minifyCssString);
66
+ var chalk__default = /*#__PURE__*/_interopDefaultLegacy(chalk);
64
67
 
65
68
  /**
66
69
  * Util class holds our search results helper boilerplate methods
@@ -679,27 +682,6 @@ const makeLinkDepthMiddleware = ({
679
682
  const servers$1 = SERVERS;
680
683
  /* global SERVERS */
681
684
 
682
- const projects = PROJECTS;
683
- /* global PROJECTS */
684
-
685
- const DisplayStartupConfiguration = config => {
686
- /* eslint-disable no-console */
687
- console.log();
688
- console.log(`Configured servers:
689
- `, JSON.stringify(servers$1, null, 2));
690
- console.log();
691
- console.log(`Configured projects:
692
- `, JSON.stringify(projects, null, 2));
693
- console.log();
694
- console.log('Reverse proxy paths: ', JSON.stringify(config.reverseProxyPaths, null, 2));
695
- console.log();
696
- if (config.staticFolderPath) console.log(`Serving static assets from: "/dist/${config.staticFolderPath}/"`);
697
- /* eslint-enable no-console */
698
- };
699
-
700
- const servers = SERVERS;
701
- /* global SERVERS */
702
-
703
685
  const project = PROJECT;
704
686
  /* global PROJECT */
705
687
 
@@ -713,7 +695,7 @@ const deliveryProxy = httpProxy__default["default"].createProxyServer();
713
695
  const reverseProxies = (app, reverseProxyPaths = []) => {
714
696
  deliveryApiProxy(deliveryProxy, app);
715
697
  app.all(reverseProxyPaths, (req, res) => {
716
- const target = req.hostname.indexOf('preview-') || req.hostname.indexOf('preview.') || req.hostname === 'localhost' ? servers.previewIis || servers.iis : servers.iis;
698
+ const target = req.hostname.indexOf('preview-') || req.hostname.indexOf('preview.') || req.hostname === 'localhost' ? servers$1.previewIis || servers$1.iis : servers$1.iis;
717
699
  assetProxy.web(req, res, {
718
700
  target,
719
701
  changeOrigin: true
@@ -730,7 +712,7 @@ const deliveryApiProxy = (apiProxy, app) => {
730
712
  // This is just here to stop cors requests on localhost. In Production this is mapped using varnish.
731
713
  app.all(['/api/delivery/*', '/api/image/*'], (req, res) => {
732
714
  /* eslint-disable no-console */
733
- console.log(`Proxying api request to ${servers.alias}`);
715
+ console.log(`Proxying api request to ${servers$1.alias}`);
734
716
  apiProxy.web(req, res, {
735
717
  target: deliveryApiHostname,
736
718
  changeOrigin: true
@@ -855,6 +837,27 @@ const staticAssets = (app, {
855
837
  }));
856
838
  };
857
839
 
840
+ const servers = SERVERS;
841
+ /* global SERVERS */
842
+
843
+ const projects = PROJECTS;
844
+ /* global PROJECTS */
845
+
846
+ const DisplayStartupConfiguration = config => {
847
+ /* eslint-disable no-console */
848
+ console.log();
849
+ console.log(`Configured servers:
850
+ `, JSON.stringify(servers, null, 2));
851
+ console.log();
852
+ console.log(`Configured projects:
853
+ `, JSON.stringify(projects, null, 2));
854
+ console.log();
855
+ console.log('Reverse proxy paths: ', JSON.stringify(config.reverseProxyPaths, null, 2));
856
+ console.log();
857
+ if (config.staticFolderPath) console.log(`Serving static assets from: "/dist/${config.staticFolderPath}/"`);
858
+ /* eslint-enable no-console */
859
+ };
860
+
858
861
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
859
862
 
860
863
  /**
@@ -4011,7 +4014,7 @@ const loadableBundleData = ({
4011
4014
  return bundle;
4012
4015
  };
4013
4016
  const loadableChunkExtractors = () => {
4014
- const commonLoadableExtractor = new server.ChunkExtractor({
4017
+ const commonLoadableExtractor = new server$1.ChunkExtractor({
4015
4018
  stats: {}
4016
4019
  });
4017
4020
 
@@ -4020,7 +4023,7 @@ const loadableChunkExtractors = () => {
4020
4023
  let legacy;
4021
4024
 
4022
4025
  try {
4023
- modern = new server.ChunkExtractor({
4026
+ modern = new server$1.ChunkExtractor({
4024
4027
  entrypoints: ['app'],
4025
4028
  namespace: 'modern',
4026
4029
  statsFile: path__default["default"].resolve('dist/modern/loadable-stats.json')
@@ -4030,7 +4033,7 @@ const loadableChunkExtractors = () => {
4030
4033
  }
4031
4034
 
4032
4035
  try {
4033
- legacy = new server.ChunkExtractor({
4036
+ legacy = new server$1.ChunkExtractor({
4034
4037
  entrypoints: ['app'],
4035
4038
  namespace: 'legacy',
4036
4039
  statsFile: path__default["default"].resolve('dist/legacy/loadable-stats.json')
@@ -4163,6 +4166,25 @@ const getVersionInfo = staticFolderPath => {
4163
4166
  }
4164
4167
  };
4165
4168
 
4169
+ /* eslint-disable no-console */
4170
+ const unhandledExceptionHandler = (handleExceptions = true) => {
4171
+ const exceptionTypes = handleExceptions === true ? ['uncaughtException', 'unhandledRejection', 'SIGTERM', 'SIGINT'] // Default exception types to add event listeners for
4172
+ : Array.isArray(handleExceptions) // In future we could accept an array of specific exception types to handle for a specific application?
4173
+ ? handleExceptions : [];
4174
+
4175
+ for (const type of exceptionTypes) {
4176
+ process.on(type, err => {
4177
+ if (err && err instanceof Error) {
4178
+ // Print a message to inform admins and developers the error should not be ignored
4179
+ console.log(`${`[contensis-react-base] ❌ ${chalk__default["default"].red.bold(`${type} - ${err.message}`)}`}`);
4180
+ console.log(chalk__default["default"].gray` - you are seeing this because we have tried to prevent the app from completely crashing - you should not ignore this problem`); // Log the error to server console
4181
+
4182
+ console.error(err);
4183
+ }
4184
+ });
4185
+ }
4186
+ };
4187
+
4166
4188
  const webApp = (app, ReactApp, config) => {
4167
4189
  const {
4168
4190
  stateType = 'immutable',
@@ -4177,13 +4199,16 @@ const webApp = (app, ReactApp, config) => {
4177
4199
  allowedGroups,
4178
4200
  globalGroups,
4179
4201
  disableSsrRedux,
4180
- handleResponses
4202
+ handleResponses,
4203
+ handleExceptions = true
4181
4204
  } = config;
4182
4205
  const staticRoutePath = config.staticRoutePath || staticFolderPath;
4183
4206
  const bundleData = getBundleData(config, staticRoutePath);
4184
4207
  const attributes = stringifyAttributes(scripts.attributes);
4185
4208
  scripts.startup = scripts.startup || startupScriptFilename;
4186
4209
  const responseHandler = typeof handleResponses === 'function' ? handleResponses : handleResponse;
4210
+ if (handleExceptions !== false) unhandledExceptionHandler(); // Create `process.on` event handlers for unhandled exceptions (Node v15+)
4211
+
4187
4212
  const versionInfo = getVersionInfo(staticFolderPath);
4188
4213
  app.get('/*', async (request, response) => {
4189
4214
  const {
@@ -4233,7 +4258,7 @@ const webApp = (app, ReactApp, config) => {
4233
4258
  const groups = allowedGroups && allowedGroups[project];
4234
4259
  store.dispatch(actions.setCurrentProject(project, groups, request.hostname));
4235
4260
  const loadableExtractor = loadableChunkExtractors();
4236
- const jsx = /*#__PURE__*/React__default["default"].createElement(server.ChunkExtractorManager, {
4261
+ const jsx = /*#__PURE__*/React__default["default"].createElement(server$1.ChunkExtractorManager, {
4237
4262
  extractor: loadableExtractor.commonLoadableExtractor
4238
4263
  }, /*#__PURE__*/React__default["default"].createElement(reactCookie.CookiesProvider, {
4239
4264
  cookies: cookies
@@ -4254,7 +4279,7 @@ const webApp = (app, ReactApp, config) => {
4254
4279
 
4255
4280
  if (accessMethod.DYNAMIC) {
4256
4281
  // Dynamic doesn't need sagas
4257
- server$1.renderToString(jsx); // Dynamic page render has only the necessary bundles to start up the app
4282
+ server$2.renderToString(jsx); // Dynamic page render has only the necessary bundles to start up the app
4258
4283
  // and does not include any react-loadable code-split bundles
4259
4284
 
4260
4285
  const bundleTags = getBundleTags(loadableExtractor, scripts, staticRoutePath);
@@ -4270,7 +4295,7 @@ const webApp = (app, ReactApp, config) => {
4270
4295
  if (!accessMethod.DYNAMIC) {
4271
4296
  store.runSaga(App.rootSaga(withSagas)).toPromise().then(() => {
4272
4297
  const sheet = new styled.ServerStyleSheet();
4273
- const html = server$1.renderToString(sheet.collectStyles(jsx));
4298
+ const html = server$2.renderToString(sheet.collectStyles(jsx));
4274
4299
  const helmet = reactHelmet.Helmet.renderStatic();
4275
4300
  reactHelmet.Helmet.rewind();
4276
4301
  const htmlAttributes = helmet.htmlAttributes.toString();
@@ -4369,13 +4394,14 @@ const webApp = (app, ReactApp, config) => {
4369
4394
  response.status(500);
4370
4395
  responseHandler(request, response, `Error occurred: <br />${err.stack} <br />${JSON.stringify(err)}`);
4371
4396
  });
4372
- server$1.renderToString(jsx);
4397
+ server$2.renderToString(jsx);
4373
4398
  store.close();
4374
4399
  }
4375
4400
  });
4376
4401
  };
4377
4402
 
4378
4403
  const app = express__default["default"]();
4404
+ let server = new http.Server(); // new Server() is just a stub to assert the type for the export
4379
4405
 
4380
4406
  const start = (ReactApp, config, ServerFeatures) => {
4381
4407
  global.PACKAGE_JSON = config.packagejson;
@@ -4392,7 +4418,7 @@ const start = (ReactApp, config, ServerFeatures) => {
4392
4418
  staticAssets(app, config);
4393
4419
  webApp(app, ReactApp, config);
4394
4420
  app.on('ready', async () => {
4395
- const server = app.listen(3001, () => {
4421
+ server = app.listen(3001, () => {
4396
4422
  console.info(`HTTP server is listening @ port 3001`);
4397
4423
  setTimeout(function () {
4398
4424
  app.emit('app_started');
@@ -4409,6 +4435,7 @@ const start = (ReactApp, config, ServerFeatures) => {
4409
4435
  var internalServer = {
4410
4436
  app,
4411
4437
  apiProxy: deliveryProxy,
4438
+ server,
4412
4439
  start
4413
4440
  };
4414
4441