@dwp/govuk-casa 8.16.1 → 8.16.3

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 (189) hide show
  1. package/dist/assets/css/casa-ie8.css +1 -1
  2. package/dist/assets/css/casa.css +1 -1
  3. package/dist/casa.d.ts +13 -13
  4. package/dist/casa.js +17 -7
  5. package/dist/casa.js.map +1 -1
  6. package/dist/lib/CasaTemplateLoader.d.ts +1 -1
  7. package/dist/lib/CasaTemplateLoader.js +13 -14
  8. package/dist/lib/CasaTemplateLoader.js.map +1 -1
  9. package/dist/lib/JourneyContext.d.ts +10 -4
  10. package/dist/lib/JourneyContext.js +57 -47
  11. package/dist/lib/JourneyContext.js.map +1 -1
  12. package/dist/lib/MutableRouter.d.ts +1 -1
  13. package/dist/lib/MutableRouter.js +22 -23
  14. package/dist/lib/MutableRouter.js.map +1 -1
  15. package/dist/lib/Plan.d.ts +5 -5
  16. package/dist/lib/Plan.js +49 -36
  17. package/dist/lib/Plan.js.map +1 -1
  18. package/dist/lib/ValidationError.d.ts +1 -1
  19. package/dist/lib/ValidationError.js +9 -9
  20. package/dist/lib/ValidationError.js.map +1 -1
  21. package/dist/lib/ValidatorFactory.js +4 -7
  22. package/dist/lib/ValidatorFactory.js.map +1 -1
  23. package/dist/lib/configuration-ingestor.d.ts +75 -14
  24. package/dist/lib/configuration-ingestor.js +156 -64
  25. package/dist/lib/configuration-ingestor.js.map +1 -1
  26. package/dist/lib/configure.js +11 -10
  27. package/dist/lib/configure.js.map +1 -1
  28. package/dist/lib/constants.js +8 -8
  29. package/dist/lib/context-id-generators.d.ts +1 -1
  30. package/dist/lib/context-id-generators.js +7 -4
  31. package/dist/lib/context-id-generators.js.map +1 -1
  32. package/dist/lib/end-session.js +2 -2
  33. package/dist/lib/field.d.ts +6 -6
  34. package/dist/lib/field.js +15 -21
  35. package/dist/lib/field.js.map +1 -1
  36. package/dist/lib/index.d.ts +13 -13
  37. package/dist/lib/index.js +17 -7
  38. package/dist/lib/index.js.map +1 -1
  39. package/dist/lib/logger.js +7 -7
  40. package/dist/lib/logger.js.map +1 -1
  41. package/dist/lib/mount.js +3 -3
  42. package/dist/lib/mount.js.map +1 -1
  43. package/dist/lib/nunjucks-filters.d.ts +5 -1
  44. package/dist/lib/nunjucks-filters.js +37 -23
  45. package/dist/lib/nunjucks-filters.js.map +1 -1
  46. package/dist/lib/nunjucks.d.ts +2 -2
  47. package/dist/lib/nunjucks.js +6 -7
  48. package/dist/lib/nunjucks.js.map +1 -1
  49. package/dist/lib/utils.js +52 -42
  50. package/dist/lib/utils.js.map +1 -1
  51. package/dist/lib/validators/dateObject.d.ts +3 -3
  52. package/dist/lib/validators/dateObject.js +44 -37
  53. package/dist/lib/validators/dateObject.js.map +1 -1
  54. package/dist/lib/validators/email.d.ts +2 -2
  55. package/dist/lib/validators/email.js +4 -5
  56. package/dist/lib/validators/email.js.map +1 -1
  57. package/dist/lib/validators/inArray.d.ts +2 -2
  58. package/dist/lib/validators/inArray.js +5 -6
  59. package/dist/lib/validators/inArray.js.map +1 -1
  60. package/dist/lib/validators/index.d.ts +10 -10
  61. package/dist/lib/validators/index.js.map +1 -1
  62. package/dist/lib/validators/nino.d.ts +2 -2
  63. package/dist/lib/validators/nino.js +10 -7
  64. package/dist/lib/validators/nino.js.map +1 -1
  65. package/dist/lib/validators/postalAddressObject.d.ts +2 -2
  66. package/dist/lib/validators/postalAddressObject.js +52 -39
  67. package/dist/lib/validators/postalAddressObject.js.map +1 -1
  68. package/dist/lib/validators/range.d.ts +2 -2
  69. package/dist/lib/validators/range.js +6 -7
  70. package/dist/lib/validators/range.js.map +1 -1
  71. package/dist/lib/validators/regex.d.ts +2 -2
  72. package/dist/lib/validators/regex.js +4 -5
  73. package/dist/lib/validators/regex.js.map +1 -1
  74. package/dist/lib/validators/required.d.ts +2 -2
  75. package/dist/lib/validators/required.js +6 -9
  76. package/dist/lib/validators/required.js.map +1 -1
  77. package/dist/lib/validators/strlen.d.ts +2 -2
  78. package/dist/lib/validators/strlen.js +8 -9
  79. package/dist/lib/validators/strlen.js.map +1 -1
  80. package/dist/lib/validators/wordCount.d.ts +2 -2
  81. package/dist/lib/validators/wordCount.js +10 -9
  82. package/dist/lib/validators/wordCount.js.map +1 -1
  83. package/dist/lib/waypoint-url.d.ts +4 -4
  84. package/dist/lib/waypoint-url.js +23 -23
  85. package/dist/lib/waypoint-url.js.map +1 -1
  86. package/dist/middleware/body-parser.d.ts +27 -5
  87. package/dist/middleware/body-parser.js +37 -6
  88. package/dist/middleware/body-parser.js.map +1 -1
  89. package/dist/middleware/csrf.d.ts +3 -0
  90. package/dist/middleware/csrf.js +3 -0
  91. package/dist/middleware/csrf.js.map +1 -1
  92. package/dist/middleware/data.d.ts +22 -5
  93. package/dist/middleware/data.js +37 -7
  94. package/dist/middleware/data.js.map +1 -1
  95. package/dist/middleware/gather-fields.d.ts +1 -1
  96. package/dist/middleware/gather-fields.js +4 -3
  97. package/dist/middleware/gather-fields.js.map +1 -1
  98. package/dist/middleware/i18n.d.ts +11 -2
  99. package/dist/middleware/i18n.js +26 -17
  100. package/dist/middleware/i18n.js.map +1 -1
  101. package/dist/middleware/post.d.ts +3 -1
  102. package/dist/middleware/post.js +35 -18
  103. package/dist/middleware/post.js.map +1 -1
  104. package/dist/middleware/pre.d.ts +1 -1
  105. package/dist/middleware/pre.js +44 -21
  106. package/dist/middleware/pre.js.map +1 -1
  107. package/dist/middleware/progress-journey.d.ts +1 -1
  108. package/dist/middleware/progress-journey.js +5 -5
  109. package/dist/middleware/progress-journey.js.map +1 -1
  110. package/dist/middleware/sanitise-fields.d.ts +2 -2
  111. package/dist/middleware/sanitise-fields.js +13 -11
  112. package/dist/middleware/sanitise-fields.js.map +1 -1
  113. package/dist/middleware/serve-first-waypoint.d.ts +1 -1
  114. package/dist/middleware/serve-first-waypoint.js +6 -4
  115. package/dist/middleware/serve-first-waypoint.js.map +1 -1
  116. package/dist/middleware/session.d.ts +27 -8
  117. package/dist/middleware/session.js +53 -25
  118. package/dist/middleware/session.js.map +1 -1
  119. package/dist/middleware/skip-waypoint.d.ts +1 -1
  120. package/dist/middleware/skip-waypoint.js +3 -3
  121. package/dist/middleware/skip-waypoint.js.map +1 -1
  122. package/dist/middleware/steer-journey.d.ts +1 -1
  123. package/dist/middleware/steer-journey.js +15 -13
  124. package/dist/middleware/steer-journey.js.map +1 -1
  125. package/dist/middleware/strip-proxy-path.d.ts +1 -1
  126. package/dist/middleware/strip-proxy-path.js +3 -3
  127. package/dist/middleware/strip-proxy-path.js.map +1 -1
  128. package/dist/middleware/validate-fields.d.ts +2 -2
  129. package/dist/middleware/validate-fields.js +2 -5
  130. package/dist/middleware/validate-fields.js.map +1 -1
  131. package/dist/routes/ancillary.d.ts +2 -2
  132. package/dist/routes/ancillary.js +3 -3
  133. package/dist/routes/ancillary.js.map +1 -1
  134. package/dist/routes/journey.d.ts +1 -1
  135. package/dist/routes/journey.js +85 -31
  136. package/dist/routes/journey.js.map +1 -1
  137. package/dist/routes/static.d.ts +2 -2
  138. package/dist/routes/static.js +18 -18
  139. package/dist/routes/static.js.map +1 -1
  140. package/package.json +39 -42
  141. package/src/casa.js +13 -13
  142. package/src/lib/CasaTemplateLoader.js +21 -17
  143. package/src/lib/JourneyContext.js +118 -79
  144. package/src/lib/MutableRouter.js +30 -26
  145. package/src/lib/Plan.js +109 -62
  146. package/src/lib/ValidationError.js +13 -10
  147. package/src/lib/ValidatorFactory.js +7 -8
  148. package/src/lib/configuration-ingestor.js +200 -74
  149. package/src/lib/configure.js +31 -30
  150. package/src/lib/constants.js +8 -8
  151. package/src/lib/context-id-generators.js +39 -38
  152. package/src/lib/end-session.js +3 -3
  153. package/src/lib/field.js +48 -32
  154. package/src/lib/index.js +12 -12
  155. package/src/lib/logger.js +9 -9
  156. package/src/lib/mount.js +68 -73
  157. package/src/lib/nunjucks-filters.js +57 -44
  158. package/src/lib/nunjucks.js +20 -16
  159. package/src/lib/utils.js +69 -44
  160. package/src/lib/validators/dateObject.js +57 -48
  161. package/src/lib/validators/email.js +8 -9
  162. package/src/lib/validators/inArray.js +8 -9
  163. package/src/lib/validators/index.js +11 -11
  164. package/src/lib/validators/nino.js +25 -12
  165. package/src/lib/validators/postalAddressObject.js +73 -55
  166. package/src/lib/validators/range.js +9 -11
  167. package/src/lib/validators/regex.js +7 -8
  168. package/src/lib/validators/required.js +13 -14
  169. package/src/lib/validators/strlen.js +11 -12
  170. package/src/lib/validators/wordCount.js +17 -12
  171. package/src/lib/waypoint-url.js +48 -33
  172. package/src/middleware/body-parser.js +44 -10
  173. package/src/middleware/csrf.js +4 -1
  174. package/src/middleware/data.js +62 -25
  175. package/src/middleware/gather-fields.js +8 -8
  176. package/src/middleware/i18n.js +49 -39
  177. package/src/middleware/post.js +47 -21
  178. package/src/middleware/pre.js +60 -35
  179. package/src/middleware/progress-journey.js +32 -18
  180. package/src/middleware/sanitise-fields.js +43 -20
  181. package/src/middleware/serve-first-waypoint.js +12 -10
  182. package/src/middleware/session.js +97 -65
  183. package/src/middleware/skip-waypoint.js +7 -9
  184. package/src/middleware/steer-journey.js +39 -27
  185. package/src/middleware/strip-proxy-path.js +8 -7
  186. package/src/middleware/validate-fields.js +5 -12
  187. package/src/routes/ancillary.js +4 -6
  188. package/src/routes/journey.js +158 -78
  189. package/src/routes/static.js +61 -28
@@ -1,10 +1,10 @@
1
1
  // This sits in front of all other middleware and prevents the user from
2
2
  // "jumping ahead" in the Plan.
3
3
 
4
- import waypointUrl from '../lib/waypoint-url.js';
5
- import logger from '../lib/logger.js';
4
+ import waypointUrl from "../lib/waypoint-url.js";
5
+ import logger from "../lib/logger.js";
6
6
 
7
- const log = logger('middleware:steer-journey');
7
+ const log = logger("middleware:steer-journey");
8
8
 
9
9
  /**
10
10
  * @access private
@@ -20,10 +20,7 @@ const log = logger('middleware:steer-journey');
20
20
  * @param {Plan} obj.plan CASA Plan
21
21
  * @returns {void}
22
22
  */
23
- export default ({
24
- waypoint,
25
- plan,
26
- }) => [
23
+ export default ({ waypoint, plan }) => [
27
24
  (req, res, next) => {
28
25
  const mountUrl = `${req.baseUrl}/`;
29
26
 
@@ -32,25 +29,38 @@ export default ({
32
29
  const traversed = plan.traverse(req.casa.journeyContext);
33
30
  if (traversed.indexOf(waypoint) === -1) {
34
31
  const redirectTo = traversed[traversed.length - 1];
35
- log.trace(`Attempted to access "${waypoint}" when not in the journey; redirecting to "${redirectTo}"`);
32
+ log.trace(
33
+ `Attempted to access "${waypoint}" when not in the journey; redirecting to "${redirectTo}"`,
34
+ );
36
35
 
37
- return res.redirect(302, waypointUrl({
38
- waypoint: redirectTo,
39
- mountUrl,
40
- journeyContext: req.casa.journeyContext,
41
- edit: req.casa.editMode,
42
- editOrigin: req.casa.editOrigin,
43
- }));
36
+ return res.redirect(
37
+ 302,
38
+ waypointUrl({
39
+ waypoint: redirectTo,
40
+ mountUrl,
41
+ journeyContext: req.casa.journeyContext,
42
+ edit: req.casa.editMode,
43
+ editOrigin: req.casa.editOrigin,
44
+ }),
45
+ );
44
46
  }
45
47
 
46
48
  // Edit mode
47
49
  // Cannot be in edit mode if we're already on the `editorigin` URL
48
50
  if (req.casa.editMode) {
49
- const { pathname: currentPathname } = new URL(req.originalUrl, 'https://placeholder.test/');
50
- const { pathname: editOriginPathname } = new URL(req.casa.editOrigin, 'https://placeholder.test/');
51
+ const { pathname: currentPathname } = new URL(
52
+ req.originalUrl,
53
+ "https://placeholder.test/",
54
+ );
55
+ const { pathname: editOriginPathname } = new URL(
56
+ req.casa.editOrigin,
57
+ "https://placeholder.test/",
58
+ );
51
59
 
52
60
  if (editOriginPathname === currentPathname) {
53
- log.debug(`Disabling edit mode as we are on the edit origin (${req.casa.editOrigin})`);
61
+ log.debug(
62
+ `Disabling edit mode as we are on the edit origin (${req.casa.editOrigin})`,
63
+ );
54
64
  req.casa.editMode = false;
55
65
  req.casa.editOrigin = undefined;
56
66
  }
@@ -64,16 +74,18 @@ export default ({
64
74
  // Calculate URL for the "back" link
65
75
  const [prevRoute] = plan.traversePrevRoutes(req.casa.journeyContext, {
66
76
  startWaypoint: waypoint,
67
- stopCondition: () => (true), // stop at the first one
77
+ stopCondition: () => true, // stop at the first one
68
78
  });
69
- res.locals.casa.journeyPreviousUrl = prevRoute.target ? waypointUrl({
70
- mountUrl,
71
- journeyContext: req.casa.journeyContext,
72
- waypoint: prevRoute.target,
73
- routeName: 'prev',
74
- edit: req.casa.editMode,
75
- editOrigin: req.casa.editOrigin,
76
- }) : undefined;
79
+ res.locals.casa.journeyPreviousUrl = prevRoute.target
80
+ ? waypointUrl({
81
+ mountUrl,
82
+ journeyContext: req.casa.journeyContext,
83
+ waypoint: prevRoute.target,
84
+ routeName: "prev",
85
+ edit: req.casa.editMode,
86
+ editOrigin: req.casa.editOrigin,
87
+ })
88
+ : undefined;
77
89
 
78
90
  return next();
79
91
  },
@@ -14,13 +14,11 @@
14
14
  //
15
15
  // See docs in `docs/guides/setup-behind-a-proxy.md`
16
16
 
17
- import logger from '../lib/logger.js';
17
+ import logger from "../lib/logger.js";
18
18
 
19
- const log = logger('casa:middleware:strip-proxy-path');
19
+ const log = logger("casa:middleware:strip-proxy-path");
20
20
 
21
- export default ({
22
- mountUrl = '/',
23
- }) => [
21
+ export default ({ mountUrl = "/" }) => [
24
22
  (req, res, next) => {
25
23
  // TODO:
26
24
  // We _may_ have to start tracking the various prefix in order to differentiate
@@ -28,7 +26,7 @@ export default ({
28
26
 
29
27
  // Assume everything before `mountUrl` is the proxy path prefix and remove it
30
28
  req.originalBaseUrl = req.originalBaseUrl ?? req.baseUrl;
31
- req.baseUrl = mountUrl.replace(/\/$/, '');
29
+ req.baseUrl = mountUrl.replace(/\/$/, "");
32
30
 
33
31
  // If the app has been mounted directly on the specific `mountUrl`, then
34
32
  // there's nothing we need to do and can let this request pass-through.
@@ -43,7 +41,10 @@ export default ({
43
41
  // req.url will already have the proxy prefix and mountUrl removed.
44
42
  /* eslint-disable security/detect-non-literal-regexp */
45
43
  log.trace(`req.originalUrl before proxy stripping: ${req.originalUrl}`);
46
- req.originalUrl = req.originalUrl.replace(new RegExp(`^/.+?${mountUrl}`), mountUrl);
44
+ req.originalUrl = req.originalUrl.replace(
45
+ new RegExp(`^/.+?${mountUrl}`),
46
+ mountUrl,
47
+ );
47
48
  log.trace(`req.originalUrl after proxy stripping: ${req.originalUrl}`);
48
49
  /* eslint-enable security/detect-non-literal-regexp */
49
50
 
@@ -1,6 +1,6 @@
1
1
  // Validate the data captured in the journey context
2
- import JourneyContext from '../lib/JourneyContext.js';
3
- import { REQUEST_PHASE_VALIDATE } from '../lib/constants.js';
2
+ import JourneyContext from "../lib/JourneyContext.js";
3
+ import { REQUEST_PHASE_VALIDATE } from "../lib/constants.js";
4
4
 
5
5
  const updateContext = ({
6
6
  waypoint,
@@ -21,13 +21,9 @@ const updateContext = ({
21
21
  casaRequestPhase: REQUEST_PHASE_VALIDATE,
22
22
  },
23
23
  });
24
- }
24
+ };
25
25
 
26
- export default ({
27
- waypoint,
28
- fields = [],
29
- plan,
30
- }) => [
26
+ export default ({ waypoint, fields = [], plan }) => [
31
27
  (req, res, next) => {
32
28
  const mountUrl = `${req.baseUrl}/`;
33
29
 
@@ -50,10 +46,7 @@ export default ({
50
46
  };
51
47
  /* eslint-enable security/detect-object-injection */
52
48
 
53
- errors = [
54
- ...errors,
55
- ...field.runValidators(fieldValue, context),
56
- ];
49
+ errors = [...errors, ...field.runValidators(fieldValue, context)];
57
50
  }
58
51
 
59
52
  // Validation passed with no errors
@@ -1,4 +1,4 @@
1
- import MutableRouter from '../lib/MutableRouter.js';
1
+ import MutableRouter from "../lib/MutableRouter.js";
2
2
 
3
3
  /**
4
4
  * @typedef {object} AncillaryRouterOptions Options to configure static router
@@ -12,15 +12,13 @@ import MutableRouter from '../lib/MutableRouter.js';
12
12
  * @param {AncillaryRouterOptions} options Options
13
13
  * @returns {MutableRouter} ExpressJS Router instance
14
14
  */
15
- export default function ancillaryRouter({
16
- sessionTtl,
17
- }) {
15
+ export default function ancillaryRouter({ sessionTtl }) {
18
16
  // Router
19
17
  const router = new MutableRouter();
20
18
 
21
19
  // Session timeout
22
- router.all('/session-timeout', (req, res) => {
23
- res.render('casa/session-timeout.njk', {
20
+ router.all("/session-timeout", (req, res) => {
21
+ res.render("casa/session-timeout.njk", {
24
22
  sessionTtl: Math.floor(sessionTtl / 60),
25
23
  });
26
24
  });
@@ -1,17 +1,21 @@
1
- /* eslint-disable object-curly-newline,max-len */
2
- import MutableRouter from '../lib/MutableRouter.js';
3
- import skipWaypointMiddlewareFactory from '../middleware/skip-waypoint.js';
4
- import steerJourneyMiddlewareFactory from '../middleware/steer-journey.js';
5
- import sanitiseFieldsMiddlewareFactory from '../middleware/sanitise-fields.js';
6
- import gatherFieldsMiddlewareFactory from '../middleware/gather-fields.js';
7
- import validateFieldsMiddlewareFactory from '../middleware/validate-fields.js';
8
- import progressJourneyMiddlewareFactory from '../middleware/progress-journey.js';
9
- import waypointUrl from '../lib/waypoint-url.js';
10
- import logger from '../lib/logger.js';
11
- import { resolveMiddlewareHooks } from '../lib/utils.js';
12
- import { CONFIG_ERROR_VISIBILITY_ALWAYS } from '../lib/constants.js';
13
-
14
- const log = logger('routes:journey');
1
+ import MutableRouter from "../lib/MutableRouter.js";
2
+ import skipWaypointMiddlewareFactory from "../middleware/skip-waypoint.js";
3
+ import steerJourneyMiddlewareFactory from "../middleware/steer-journey.js";
4
+ import sanitiseFieldsMiddlewareFactory from "../middleware/sanitise-fields.js";
5
+ import gatherFieldsMiddlewareFactory from "../middleware/gather-fields.js";
6
+ import validateFieldsMiddlewareFactory from "../middleware/validate-fields.js";
7
+ import progressJourneyMiddlewareFactory from "../middleware/progress-journey.js";
8
+ import waypointUrl from "../lib/waypoint-url.js";
9
+ import logger from "../lib/logger.js";
10
+ import { resolveMiddlewareHooks } from "../lib/utils.js";
11
+ import { CONFIG_ERROR_VISIBILITY_ALWAYS } from "../lib/constants.js";
12
+
13
+ const log = logger("routes:journey");
14
+
15
+ /**
16
+ * @access private
17
+ * @param {import('express').RequestHandler} RequestHandler
18
+ */
15
19
 
16
20
  /**
17
21
  * @access private
@@ -38,20 +42,27 @@ const log = logger('routes:journey');
38
42
 
39
43
  const renderMiddlewareFactory = (view, contextFactory) => [
40
44
  (req, res, next) => {
41
- res.render(view, {
42
- // Common template variables for both GET and POST requests
43
- inEditMode: req.casa.editMode,
44
- editOriginUrl: req.casa.editOrigin,
45
- editCancelUrl: generateEditCancelUrl(req.casa.editOrigin, req.casa.waypoint),
46
- activeContextId: req.casa.journeyContext.identity.id,
47
- ...contextFactory(req),
48
- }, (err, templateString) => {
49
- if (err) {
50
- next(err);
51
- } else {
52
- res.send(templateString);
53
- }
54
- });
45
+ res.render(
46
+ view,
47
+ {
48
+ // Common template variables for both GET and POST requests
49
+ inEditMode: req.casa.editMode,
50
+ editOriginUrl: req.casa.editOrigin,
51
+ editCancelUrl: generateEditCancelUrl(
52
+ req.casa.editOrigin,
53
+ req.casa.waypoint,
54
+ ),
55
+ activeContextId: req.casa.journeyContext.identity.id,
56
+ ...contextFactory(req),
57
+ },
58
+ (err, templateString) => {
59
+ if (err) {
60
+ next(err);
61
+ } else {
62
+ res.send(templateString);
63
+ }
64
+ },
65
+ );
55
66
  },
56
67
  ];
57
68
 
@@ -62,25 +73,29 @@ const renderMiddlewareFactory = (view, contextFactory) => [
62
73
  * @param {object} req casa request object
63
74
  * @returns {object[]} array of error objects
64
75
  */
65
- const generateGovukErrors = (errors, req) => Object.values(errors || {}).map(([error]) => ({
66
- text: req.t(error.summary, error.variables),
67
- href: error.fieldHref,
68
- }))
76
+ const generateGovukErrors = (errors, req) =>
77
+ Object.values(errors || {}).map(([error]) => ({
78
+ text: req.t(error.summary, error.variables),
79
+ href: error.fieldHref,
80
+ }));
69
81
 
70
82
  const generateEditCancelUrl = (editOrigin, waypoint) => {
71
- const url = new URL(editOrigin, 'https://placeholder.test/');
72
- url.searchParams.set('editcancel', waypoint);
83
+ const url = new URL(editOrigin, "https://placeholder.test/");
84
+ url.searchParams.set("editcancel", waypoint);
73
85
  return `${url.pathname}${url.search}`;
74
86
  };
75
87
 
76
88
  /**
77
89
  * handle errorVisibility flag and function and return boolean
78
90
  *
91
+ * @param {RequestHandler} req casa request object
79
92
  * @param {symbol | Function} errorVisibility errorVisibility config option
80
- * @param {object} req casa request object
81
93
  * @returns {boolean} true if errorVisibility is "always" or function condition true
82
94
  */
83
- const resolveErrorVisibility = (req, errorVisibility) => (typeof errorVisibility === 'function' ? errorVisibility({ req }) : errorVisibility === CONFIG_ERROR_VISIBILITY_ALWAYS)
95
+ const resolveErrorVisibility = (req, errorVisibility) =>
96
+ typeof errorVisibility === "function"
97
+ ? errorVisibility({ req })
98
+ : errorVisibility === CONFIG_ERROR_VISIBILITY_ALWAYS;
84
99
 
85
100
  /**
86
101
  * Create an instance of the router for all waypoints visited during a Journey
@@ -102,7 +117,7 @@ export default function journeyRouter({
102
117
 
103
118
  // Special "_" route which handles redirecting the user between sub-apps
104
119
  // /app1/_/?refmount=app2&route=prev
105
- router.all('/_', (req, res) => {
120
+ router.all("/_", (req, res) => {
106
121
  const mountUrl = `${req.baseUrl}/`;
107
122
  const refmount = req.query?.refmount;
108
123
  const route = req.query?.route;
@@ -112,7 +127,7 @@ export default function journeyRouter({
112
127
  const fallback = waypointUrl({
113
128
  mountUrl,
114
129
  waypoint: plan.traverse(req.casa.journeyContext, {
115
- stopCondition: () => (true), // we only need one; stop at the first
130
+ stopCondition: () => true, // we only need one; stop at the first
116
131
  })[0],
117
132
  });
118
133
 
@@ -121,37 +136,49 @@ export default function journeyRouter({
121
136
  // the user to our Plan and we don't intend to link back.
122
137
  if (!plan.getWaypoints().includes(refmount)) {
123
138
  redirectTo = fallback;
124
- } else if (route === 'prev') {
125
- const routes = plan.traversePrevRoutes(req.casa.journeyContext, { startWaypoint: refmount });
126
- redirectTo = routes.length ? waypointUrl({ mountUrl, waypoint: routes[0].target }) : fallback;
139
+ } else if (route === "prev") {
140
+ const routes = plan.traversePrevRoutes(req.casa.journeyContext, {
141
+ startWaypoint: refmount,
142
+ });
143
+ redirectTo = routes.length
144
+ ? waypointUrl({ mountUrl, waypoint: routes[0].target })
145
+ : fallback;
127
146
  } else {
128
- const routes = plan.traverseNextRoutes(req.casa.journeyContext, { startWaypoint: refmount });
147
+ const routes = plan.traverseNextRoutes(req.casa.journeyContext, {
148
+ startWaypoint: refmount,
149
+ });
129
150
  if (routes[0].target !== null) {
130
- redirectTo = routes.length ? waypointUrl({ mountUrl, waypoint: routes[0].target }) : fallback;
151
+ redirectTo = routes.length
152
+ ? waypointUrl({ mountUrl, waypoint: routes[0].target })
153
+ : fallback;
131
154
  } else {
132
155
  redirectTo = fallback;
133
156
  }
134
157
  }
135
158
 
136
159
  // Carry over any params
137
- const url = new URL(redirectTo, 'https://placeholder.test/');
160
+ const url = new URL(redirectTo, "https://placeholder.test/");
138
161
  const searchParams = new URLSearchParams(req.query);
139
- searchParams.delete('refmount');
140
- searchParams.delete('route');
162
+ searchParams.delete("refmount");
163
+ searchParams.delete("route");
141
164
  url.search = searchParams.toString();
142
- redirectTo = `${url.pathname.replace(/\/+/g, '/')}${url.search}`;
165
+ redirectTo = `${url.pathname.replace(/\/+/g, "/")}${url.search}`;
143
166
 
144
167
  log.trace(`Redirect to ${redirectTo}`);
145
168
  return res.redirect(redirectTo);
146
169
  });
147
170
 
148
171
  // Create GET / POST routes for each page
149
- const commonMiddleware = [
150
- ...csrfMiddleware,
151
- ];
172
+ const commonMiddleware = [...csrfMiddleware];
152
173
 
153
174
  pages.forEach((page) => {
154
- const { waypoint, view, hooks: pageHooks = [], fields, errorVisibility } = page;
175
+ const {
176
+ waypoint,
177
+ view,
178
+ hooks: pageHooks = [],
179
+ fields,
180
+ errorVisibility,
181
+ } = page;
155
182
  const waypointPath = `/${waypoint}`;
156
183
 
157
184
  let commonWaypointMiddleware = [
@@ -175,22 +202,40 @@ export default function journeyRouter({
175
202
  ...commonMiddleware,
176
203
  ...commonWaypointMiddleware,
177
204
 
178
- ...resolveMiddlewareHooks('journey.presteer', waypointPath, [...globalHooks, ...pageHooks]),
205
+ ...resolveMiddlewareHooks("journey.presteer", waypointPath, [
206
+ ...globalHooks,
207
+ ...pageHooks,
208
+ ]),
179
209
  ...steerJourneyMiddlewareFactory({ waypoint, plan }),
180
- ...resolveMiddlewareHooks('journey.poststeer', waypointPath, [...globalHooks, ...pageHooks]),
181
-
182
- ...resolveMiddlewareHooks('journey.prerender', waypointPath, [...globalHooks, ...pageHooks]),
210
+ ...resolveMiddlewareHooks("journey.poststeer", waypointPath, [
211
+ ...globalHooks,
212
+ ...pageHooks,
213
+ ]),
214
+
215
+ ...resolveMiddlewareHooks("journey.prerender", waypointPath, [
216
+ ...globalHooks,
217
+ ...pageHooks,
218
+ ]),
183
219
  renderMiddlewareFactory(view, (req) => {
184
- const displayErrors = resolveErrorVisibility(req, globalErrorVisibility) || resolveErrorVisibility(req, errorVisibility);
185
- const errors = displayErrors && (req.casa.journeyContext.getValidationErrorsForPageByField(waypoint) ?? Object.create(null));
220
+ const displayErrors =
221
+ resolveErrorVisibility(req, globalErrorVisibility) ||
222
+ resolveErrorVisibility(req, errorVisibility);
223
+ const errors =
224
+ displayErrors &&
225
+ (req.casa.journeyContext.getValidationErrorsForPageByField(
226
+ waypoint,
227
+ ) ??
228
+ Object.create(null));
186
229
  const govukErrors = displayErrors && generateGovukErrors(errors, req);
187
230
 
188
- return ({
231
+ return {
189
232
  formUrl: waypointUrl({ mountUrl: `${req.baseUrl}/`, waypoint }),
190
233
  formData: req.casa.journeyContext.getDataForPage(waypoint),
191
- formErrors: (Object.keys(errors).length && displayErrors) ? errors : null,
192
- formErrorsGovukArray: (govukErrors.length && displayErrors) ? govukErrors : null,
193
- })
234
+ formErrors:
235
+ Object.keys(errors).length && displayErrors ? errors : null,
236
+ formErrorsGovukArray:
237
+ govukErrors.length && displayErrors ? govukErrors : null,
238
+ };
194
239
  }),
195
240
  );
196
241
 
@@ -199,35 +244,70 @@ export default function journeyRouter({
199
244
  ...commonMiddleware,
200
245
  ...commonWaypointMiddleware,
201
246
 
202
- ...resolveMiddlewareHooks('journey.presteer', waypointPath, [...globalHooks, ...pageHooks]),
247
+ ...resolveMiddlewareHooks("journey.presteer", waypointPath, [
248
+ ...globalHooks,
249
+ ...pageHooks,
250
+ ]),
203
251
  ...steerJourneyMiddlewareFactory({ waypoint, plan }),
204
- ...resolveMiddlewareHooks('journey.poststeer', waypointPath, [...globalHooks, ...pageHooks]),
205
-
206
- ...resolveMiddlewareHooks('journey.presanitise', waypointPath, [...globalHooks, ...pageHooks]),
252
+ ...resolveMiddlewareHooks("journey.poststeer", waypointPath, [
253
+ ...globalHooks,
254
+ ...pageHooks,
255
+ ]),
256
+
257
+ ...resolveMiddlewareHooks("journey.presanitise", waypointPath, [
258
+ ...globalHooks,
259
+ ...pageHooks,
260
+ ]),
207
261
  ...sanitiseFieldsMiddlewareFactory({ waypoint, fields }),
208
- ...resolveMiddlewareHooks('journey.postsanitise', waypointPath, [...globalHooks, ...pageHooks]),
209
-
210
- ...resolveMiddlewareHooks('journey.pregather', waypointPath, [...globalHooks, ...pageHooks]),
262
+ ...resolveMiddlewareHooks("journey.postsanitise", waypointPath, [
263
+ ...globalHooks,
264
+ ...pageHooks,
265
+ ]),
266
+
267
+ ...resolveMiddlewareHooks("journey.pregather", waypointPath, [
268
+ ...globalHooks,
269
+ ...pageHooks,
270
+ ]),
211
271
  ...gatherFieldsMiddlewareFactory({ waypoint, fields }),
212
- ...resolveMiddlewareHooks('journey.postgather', waypointPath, [...globalHooks, ...pageHooks]),
213
-
214
- ...resolveMiddlewareHooks('journey.prevalidate', waypointPath, [...globalHooks, ...pageHooks]),
272
+ ...resolveMiddlewareHooks("journey.postgather", waypointPath, [
273
+ ...globalHooks,
274
+ ...pageHooks,
275
+ ]),
276
+
277
+ ...resolveMiddlewareHooks("journey.prevalidate", waypointPath, [
278
+ ...globalHooks,
279
+ ...pageHooks,
280
+ ]),
215
281
  ...validateFieldsMiddlewareFactory({ waypoint, fields, plan }),
216
- ...resolveMiddlewareHooks('journey.postvalidate', waypointPath, [...globalHooks, ...pageHooks]),
282
+ ...resolveMiddlewareHooks("journey.postvalidate", waypointPath, [
283
+ ...globalHooks,
284
+ ...pageHooks,
285
+ ]),
217
286
 
218
287
  // If there were validation errors, jump out of this route and into the
219
288
  // next, where the errors will be rendered
220
- (req, res, next) => (req.casa.journeyContext.hasValidationErrorsForPage(waypoint) ? next('route') : next()),
221
-
222
- ...resolveMiddlewareHooks('journey.preredirect', waypointPath, [...globalHooks, ...pageHooks]),
289
+ (req, res, next) =>
290
+ req.casa.journeyContext.hasValidationErrorsForPage(waypoint)
291
+ ? next("route")
292
+ : next(),
293
+
294
+ ...resolveMiddlewareHooks("journey.preredirect", waypointPath, [
295
+ ...globalHooks,
296
+ ...pageHooks,
297
+ ]),
223
298
  ...progressJourneyMiddlewareFactory({ waypoint, plan }),
224
299
  );
225
300
 
226
301
  router.post(
227
302
  waypointPath,
228
- ...resolveMiddlewareHooks('journey.prerender', waypointPath, [...globalHooks, ...pageHooks]),
303
+ ...resolveMiddlewareHooks("journey.prerender", waypointPath, [
304
+ ...globalHooks,
305
+ ...pageHooks,
306
+ ]),
229
307
  renderMiddlewareFactory(view, (req) => {
230
- const errors = req.casa.journeyContext.getValidationErrorsForPageByField(waypoint) ?? Object.create(null);
308
+ const errors =
309
+ req.casa.journeyContext.getValidationErrorsForPageByField(waypoint) ??
310
+ Object.create(null);
231
311
 
232
312
  // This is a convenience for the template. The `govukErrorSummary` macro
233
313
  // requires the errors be in a particular format, so here we provide our
@@ -236,7 +316,7 @@ export default function journeyRouter({
236
316
  // first one is shown.
237
317
  // Disabling security/detect-object-injection rule because both `errors`
238
318
  // and the `k` property are known entities
239
- const govukErrors = generateGovukErrors(errors, req)
319
+ const govukErrors = generateGovukErrors(errors, req);
240
320
 
241
321
  return {
242
322
  formUrl: waypointUrl({ mountUrl: `${req.baseUrl}/`, waypoint }),