@dwp/govuk-casa 9.7.0 → 10.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 (277) hide show
  1. package/dist/assets/css/casa.css +1 -1
  2. package/dist/assets/css/casa.css.map +1 -1
  3. package/dist/casa.d.ts +81 -41
  4. package/dist/casa.d.ts.map +1 -0
  5. package/dist/casa.js +72 -99
  6. package/dist/core-plugins/edit-snapshot/src/configure.d.ts +1 -0
  7. package/dist/core-plugins/edit-snapshot/src/configure.d.ts.map +1 -0
  8. package/dist/core-plugins/edit-snapshot/src/configure.js +7 -14
  9. package/dist/core-plugins/edit-snapshot/src/index.d.ts +1 -0
  10. package/dist/core-plugins/edit-snapshot/src/index.d.ts.map +1 -0
  11. package/dist/core-plugins/edit-snapshot/src/index.js +3 -9
  12. package/dist/core-plugins/edit-snapshot/src/post-steer-hook.d.ts +2 -1
  13. package/dist/core-plugins/edit-snapshot/src/post-steer-hook.d.ts.map +1 -0
  14. package/dist/core-plugins/edit-snapshot/src/post-steer-hook.js +8 -13
  15. package/dist/core-plugins/edit-snapshot/src/pre-steer-hook.d.ts +2 -1
  16. package/dist/core-plugins/edit-snapshot/src/pre-steer-hook.d.ts.map +1 -0
  17. package/dist/core-plugins/edit-snapshot/src/pre-steer-hook.js +13 -18
  18. package/dist/core-plugins/edit-snapshot/src/utils.d.ts +8 -5
  19. package/dist/core-plugins/edit-snapshot/src/utils.d.ts.map +1 -0
  20. package/dist/core-plugins/edit-snapshot/src/utils.js +37 -19
  21. package/dist/core-plugins/index.d.ts +1 -0
  22. package/dist/core-plugins/index.d.ts.map +1 -0
  23. package/dist/core-plugins/index.js +1 -9
  24. package/dist/lib/CasaTemplateLoader.d.ts +1 -0
  25. package/dist/lib/CasaTemplateLoader.d.ts.map +1 -0
  26. package/dist/lib/CasaTemplateLoader.js +2 -6
  27. package/dist/lib/JourneyContext.d.ts +22 -11
  28. package/dist/lib/JourneyContext.d.ts.map +1 -0
  29. package/dist/lib/JourneyContext.js +40 -45
  30. package/dist/lib/MutableRouter.d.ts +74 -55
  31. package/dist/lib/MutableRouter.d.ts.map +1 -0
  32. package/dist/lib/MutableRouter.js +48 -45
  33. package/dist/lib/NullObject.d.ts +3 -0
  34. package/dist/lib/NullObject.d.ts.map +1 -0
  35. package/dist/lib/NullObject.js +3 -0
  36. package/dist/lib/Plan.d.ts +2 -1
  37. package/dist/lib/Plan.d.ts.map +1 -0
  38. package/dist/lib/Plan.js +44 -62
  39. package/dist/lib/ValidationError.d.ts +2 -1
  40. package/dist/lib/ValidationError.d.ts.map +1 -0
  41. package/dist/lib/ValidationError.js +3 -11
  42. package/dist/lib/ValidatorFactory.d.ts +5 -6
  43. package/dist/lib/ValidatorFactory.d.ts.map +1 -0
  44. package/dist/lib/ValidatorFactory.js +4 -12
  45. package/dist/lib/configuration-ingestor.d.ts +10 -22
  46. package/dist/lib/configuration-ingestor.d.ts.map +1 -0
  47. package/dist/lib/configuration-ingestor.js +61 -143
  48. package/dist/lib/configure.d.ts +2 -1
  49. package/dist/lib/configure.d.ts.map +1 -0
  50. package/dist/lib/configure.js +40 -52
  51. package/dist/lib/constants.d.ts +1 -0
  52. package/dist/lib/constants.d.ts.map +1 -0
  53. package/dist/lib/constants.js +8 -12
  54. package/dist/lib/context-id-generators.d.ts +1 -0
  55. package/dist/lib/context-id-generators.d.ts.map +1 -0
  56. package/dist/lib/context-id-generators.js +4 -9
  57. package/dist/lib/end-session.d.ts +2 -1
  58. package/dist/lib/end-session.d.ts.map +1 -0
  59. package/dist/lib/end-session.js +4 -11
  60. package/dist/lib/field.d.ts +2 -1
  61. package/dist/lib/field.d.ts.map +1 -0
  62. package/dist/lib/field.js +11 -21
  63. package/dist/lib/index.d.ts +1 -0
  64. package/dist/lib/index.d.ts.map +1 -0
  65. package/dist/lib/index.js +13 -65
  66. package/dist/lib/logger.d.ts +25 -2
  67. package/dist/lib/logger.d.ts.map +1 -0
  68. package/dist/lib/logger.js +18 -9
  69. package/dist/lib/mount.d.ts +1 -0
  70. package/dist/lib/mount.d.ts.map +1 -0
  71. package/dist/lib/mount.js +10 -16
  72. package/dist/lib/nunjucks-filters.d.ts +7 -3
  73. package/dist/lib/nunjucks-filters.d.ts.map +1 -0
  74. package/dist/lib/nunjucks-filters.js +58 -71
  75. package/dist/lib/nunjucks.d.ts +2 -2
  76. package/dist/lib/nunjucks.d.ts.map +1 -0
  77. package/dist/lib/nunjucks.js +12 -25
  78. package/dist/lib/utils.d.ts +4 -2
  79. package/dist/lib/utils.d.ts.map +1 -0
  80. package/dist/lib/utils.js +14 -28
  81. package/dist/lib/validators/dateObject.d.ts +1 -0
  82. package/dist/lib/validators/dateObject.d.ts.map +1 -0
  83. package/dist/lib/validators/dateObject.js +14 -21
  84. package/dist/lib/validators/email.d.ts +1 -0
  85. package/dist/lib/validators/email.d.ts.map +1 -0
  86. package/dist/lib/validators/email.js +8 -15
  87. package/dist/lib/validators/inArray.d.ts +1 -0
  88. package/dist/lib/validators/inArray.d.ts.map +1 -0
  89. package/dist/lib/validators/inArray.js +8 -15
  90. package/dist/lib/validators/index.d.ts +1 -0
  91. package/dist/lib/validators/index.d.ts.map +1 -0
  92. package/dist/lib/validators/index.js +21 -27
  93. package/dist/lib/validators/nino.d.ts +1 -0
  94. package/dist/lib/validators/nino.d.ts.map +1 -0
  95. package/dist/lib/validators/nino.js +6 -13
  96. package/dist/lib/validators/postalAddressObject.d.ts +1 -0
  97. package/dist/lib/validators/postalAddressObject.d.ts.map +1 -0
  98. package/dist/lib/validators/postalAddressObject.js +12 -19
  99. package/dist/lib/validators/range.d.ts +1 -0
  100. package/dist/lib/validators/range.d.ts.map +1 -0
  101. package/dist/lib/validators/range.js +6 -13
  102. package/dist/lib/validators/regex.d.ts +1 -0
  103. package/dist/lib/validators/regex.d.ts.map +1 -0
  104. package/dist/lib/validators/regex.js +6 -13
  105. package/dist/lib/validators/required.d.ts +1 -0
  106. package/dist/lib/validators/required.d.ts.map +1 -0
  107. package/dist/lib/validators/required.js +9 -17
  108. package/dist/lib/validators/strlen.d.ts +1 -0
  109. package/dist/lib/validators/strlen.d.ts.map +1 -0
  110. package/dist/lib/validators/strlen.js +6 -13
  111. package/dist/lib/validators/wordCount.d.ts +1 -0
  112. package/dist/lib/validators/wordCount.d.ts.map +1 -0
  113. package/dist/lib/validators/wordCount.js +6 -13
  114. package/dist/lib/waypoint-url.d.ts +3 -2
  115. package/dist/lib/waypoint-url.d.ts.map +1 -0
  116. package/dist/lib/waypoint-url.js +12 -19
  117. package/dist/middleware/body-parser.d.ts +1 -0
  118. package/dist/middleware/body-parser.d.ts.map +1 -0
  119. package/dist/middleware/body-parser.js +4 -9
  120. package/dist/middleware/csrf.d.ts +1 -0
  121. package/dist/middleware/csrf.d.ts.map +1 -0
  122. package/dist/middleware/csrf.js +4 -8
  123. package/dist/middleware/data.d.ts +2 -3
  124. package/dist/middleware/data.d.ts.map +1 -0
  125. package/dist/middleware/data.js +23 -25
  126. package/dist/middleware/gather-fields.d.ts +3 -1
  127. package/dist/middleware/gather-fields.d.ts.map +1 -0
  128. package/dist/middleware/gather-fields.js +13 -14
  129. package/dist/middleware/i18n.d.ts +1 -0
  130. package/dist/middleware/i18n.d.ts.map +1 -0
  131. package/dist/middleware/i18n.js +26 -31
  132. package/dist/middleware/post.d.ts +1 -0
  133. package/dist/middleware/post.d.ts.map +1 -0
  134. package/dist/middleware/post.js +3 -10
  135. package/dist/middleware/pre.d.ts +2 -1
  136. package/dist/middleware/pre.d.ts.map +1 -0
  137. package/dist/middleware/pre.js +6 -12
  138. package/dist/middleware/progress-journey.d.ts +5 -3
  139. package/dist/middleware/progress-journey.d.ts.map +1 -0
  140. package/dist/middleware/progress-journey.js +20 -18
  141. package/dist/middleware/sanitise-fields.d.ts +5 -3
  142. package/dist/middleware/sanitise-fields.d.ts.map +1 -0
  143. package/dist/middleware/sanitise-fields.js +25 -17
  144. package/dist/middleware/serve-first-waypoint.d.ts +1 -0
  145. package/dist/middleware/serve-first-waypoint.d.ts.map +1 -0
  146. package/dist/middleware/serve-first-waypoint.js +3 -6
  147. package/dist/middleware/session.d.ts +15 -0
  148. package/dist/middleware/session.d.ts.map +1 -0
  149. package/dist/middleware/session.js +53 -57
  150. package/dist/middleware/skip-waypoint.d.ts +3 -2
  151. package/dist/middleware/skip-waypoint.d.ts.map +1 -0
  152. package/dist/middleware/skip-waypoint.js +15 -14
  153. package/dist/middleware/steer-journey.d.ts +2 -1
  154. package/dist/middleware/steer-journey.d.ts.map +1 -0
  155. package/dist/middleware/steer-journey.js +7 -13
  156. package/dist/middleware/strip-proxy-path.d.ts +3 -2
  157. package/dist/middleware/strip-proxy-path.d.ts.map +1 -0
  158. package/dist/middleware/strip-proxy-path.js +24 -24
  159. package/dist/middleware/validate-fields.d.ts +7 -4
  160. package/dist/middleware/validate-fields.d.ts.map +1 -0
  161. package/dist/middleware/validate-fields.js +22 -11
  162. package/dist/routes/ancillary.d.ts +1 -0
  163. package/dist/routes/ancillary.d.ts.map +1 -0
  164. package/dist/routes/ancillary.js +3 -10
  165. package/dist/routes/journey.d.ts +7 -2
  166. package/dist/routes/journey.d.ts.map +1 -0
  167. package/dist/routes/journey.js +56 -55
  168. package/dist/routes/static.d.ts +1 -0
  169. package/dist/routes/static.d.ts.map +1 -0
  170. package/dist/routes/static.js +15 -23
  171. package/package.json +20 -26
  172. package/src/casa.js +49 -29
  173. package/src/core-plugins/edit-snapshot/src/post-steer-hook.js +1 -0
  174. package/src/core-plugins/edit-snapshot/src/pre-steer-hook.js +2 -1
  175. package/src/core-plugins/edit-snapshot/src/utils.js +29 -1
  176. package/src/lib/JourneyContext.js +31 -28
  177. package/src/lib/MutableRouter.js +47 -38
  178. package/src/lib/NullObject.js +4 -0
  179. package/src/lib/Plan.js +41 -55
  180. package/src/lib/ValidationError.js +2 -4
  181. package/src/lib/ValidatorFactory.js +3 -5
  182. package/src/lib/configuration-ingestor.js +18 -38
  183. package/src/lib/configure.js +7 -10
  184. package/src/lib/end-session.js +1 -1
  185. package/src/lib/field.js +7 -12
  186. package/src/lib/logger.js +16 -0
  187. package/src/lib/mount.js +1 -1
  188. package/src/lib/nunjucks-filters.js +51 -61
  189. package/src/lib/nunjucks.js +3 -12
  190. package/src/lib/utils.js +2 -1
  191. package/src/lib/validators/dateObject.js +3 -4
  192. package/src/lib/validators/postalAddressObject.js +6 -7
  193. package/src/lib/validators/required.js +1 -3
  194. package/src/lib/waypoint-url.js +15 -19
  195. package/src/middleware/csrf.js +1 -1
  196. package/src/middleware/data.js +13 -13
  197. package/src/middleware/gather-fields.js +8 -2
  198. package/src/middleware/i18n.js +9 -6
  199. package/src/middleware/pre.js +1 -1
  200. package/src/middleware/progress-journey.js +8 -0
  201. package/src/middleware/sanitise-fields.js +17 -2
  202. package/src/middleware/session.js +53 -12
  203. package/src/middleware/skip-waypoint.js +8 -1
  204. package/src/middleware/steer-journey.js +1 -1
  205. package/src/middleware/strip-proxy-path.js +21 -16
  206. package/src/middleware/validate-fields.js +19 -0
  207. package/src/routes/journey.js +18 -8
  208. package/src/routes/static.js +5 -4
  209. package/views/casa/layouts/journey.njk +1 -1
  210. package/views/casa/layouts/main.njk +11 -21
  211. package/dist/casa.js.map +0 -1
  212. package/dist/core-plugins/edit-snapshot/src/configure.js.map +0 -1
  213. package/dist/core-plugins/edit-snapshot/src/index.js.map +0 -1
  214. package/dist/core-plugins/edit-snapshot/src/post-steer-hook.js.map +0 -1
  215. package/dist/core-plugins/edit-snapshot/src/pre-steer-hook.js.map +0 -1
  216. package/dist/core-plugins/edit-snapshot/src/utils.js.map +0 -1
  217. package/dist/core-plugins/index.js.map +0 -1
  218. package/dist/lib/CasaTemplateLoader.js.map +0 -1
  219. package/dist/lib/JourneyContext.js.map +0 -1
  220. package/dist/lib/MutableRouter.js.map +0 -1
  221. package/dist/lib/Plan.js.map +0 -1
  222. package/dist/lib/ValidationError.js.map +0 -1
  223. package/dist/lib/ValidatorFactory.js.map +0 -1
  224. package/dist/lib/configuration-ingestor.js.map +0 -1
  225. package/dist/lib/configure.js.map +0 -1
  226. package/dist/lib/constants.js.map +0 -1
  227. package/dist/lib/context-id-generators.js.map +0 -1
  228. package/dist/lib/dirname.cjs +0 -1
  229. package/dist/lib/dirname.d.cts +0 -2
  230. package/dist/lib/end-session.js.map +0 -1
  231. package/dist/lib/field.js.map +0 -1
  232. package/dist/lib/index.js.map +0 -1
  233. package/dist/lib/logger.js.map +0 -1
  234. package/dist/lib/mount.js.map +0 -1
  235. package/dist/lib/nunjucks-filters.js.map +0 -1
  236. package/dist/lib/nunjucks.js.map +0 -1
  237. package/dist/lib/utils.js.map +0 -1
  238. package/dist/lib/validators/dateObject.js.map +0 -1
  239. package/dist/lib/validators/email.js.map +0 -1
  240. package/dist/lib/validators/inArray.js.map +0 -1
  241. package/dist/lib/validators/index.js.map +0 -1
  242. package/dist/lib/validators/nino.js.map +0 -1
  243. package/dist/lib/validators/postalAddressObject.js.map +0 -1
  244. package/dist/lib/validators/range.js.map +0 -1
  245. package/dist/lib/validators/regex.js.map +0 -1
  246. package/dist/lib/validators/required.js.map +0 -1
  247. package/dist/lib/validators/strlen.js.map +0 -1
  248. package/dist/lib/validators/wordCount.js.map +0 -1
  249. package/dist/lib/waypoint-url.js.map +0 -1
  250. package/dist/middleware/body-parser.js.map +0 -1
  251. package/dist/middleware/csrf.js.map +0 -1
  252. package/dist/middleware/data.js.map +0 -1
  253. package/dist/middleware/dirname.cjs +0 -1
  254. package/dist/middleware/dirname.d.cts +0 -2
  255. package/dist/middleware/gather-fields.js.map +0 -1
  256. package/dist/middleware/i18n.js.map +0 -1
  257. package/dist/middleware/post.js.map +0 -1
  258. package/dist/middleware/pre.js.map +0 -1
  259. package/dist/middleware/progress-journey.js.map +0 -1
  260. package/dist/middleware/sanitise-fields.js.map +0 -1
  261. package/dist/middleware/serve-first-waypoint.js.map +0 -1
  262. package/dist/middleware/session.js.map +0 -1
  263. package/dist/middleware/skip-waypoint.js.map +0 -1
  264. package/dist/middleware/steer-journey.js.map +0 -1
  265. package/dist/middleware/strip-proxy-path.js.map +0 -1
  266. package/dist/middleware/validate-fields.js.map +0 -1
  267. package/dist/mjs/esm-wrapper.js +0 -20
  268. package/dist/mjs/package.json +0 -3
  269. package/dist/package.json +0 -3
  270. package/dist/routes/ancillary.js.map +0 -1
  271. package/dist/routes/dirname.cjs +0 -1
  272. package/dist/routes/dirname.d.cts +0 -2
  273. package/dist/routes/journey.js.map +0 -1
  274. package/dist/routes/static.js.map +0 -1
  275. package/src/lib/dirname.cjs +0 -1
  276. package/src/middleware/dirname.cjs +0 -1
  277. package/src/routes/dirname.cjs +0 -1
@@ -1,10 +1,15 @@
1
1
  /* eslint-disable security/detect-object-injection */
2
2
  import { JourneyContext } from "../../../casa.js";
3
+ import NullObject from "../../../lib/NullObject.js";
3
4
 
4
5
  const SESSION_KEY = "casa_edit_snapshots";
5
6
 
6
7
  export const FLAG_FOR_PURGING = Symbol("flag_to_purge_edit_snapshot");
7
8
 
9
+ /**
10
+ * @param {ExpressRequest} req Express request
11
+ * @returns {undefined | boolean} Whether the snapshot exists
12
+ */
8
13
  export const snapshotExists = (req) => {
9
14
  return (
10
15
  req?.session[SESSION_KEY] &&
@@ -12,6 +17,11 @@ export const snapshotExists = (req) => {
12
17
  );
13
18
  };
14
19
 
20
+ /**
21
+ * @param {CASADebugLogger} log Express request
22
+ * @param {ExpressRequest} req Express request
23
+ * @returns {boolean} Reached edit origin
24
+ */
15
25
  export const reachedEditOrigin = (log, req) => {
16
26
  const { pathname: currentPathname } = new URL(
17
27
  req.originalUrl,
@@ -25,15 +35,25 @@ export const reachedEditOrigin = (log, req) => {
25
35
  return editOriginPathname === currentPathname;
26
36
  };
27
37
 
38
+ /**
39
+ * @param {CASADebugLogger} log Express request
40
+ * @param {ExpressRequest} req Express request
41
+ * @returns {void}
42
+ */
28
43
  export const createSnapshot = (log, req) => {
29
44
  log.debug(
30
45
  `Creating a new edit snapshot for context '${req.casa.journeyContext.identity.id}'`,
31
46
  );
32
- req.session[SESSION_KEY] ??= Object.create(null);
47
+ req.session[SESSION_KEY] ??= new NullObject();
33
48
  req.session[SESSION_KEY][req.casa.journeyContext.identity.id] =
34
49
  req.casa.journeyContext.toObject();
35
50
  };
36
51
 
52
+ /**
53
+ * @param {CASADebugLogger} log Express request
54
+ * @param {ExpressRequest} req Express request
55
+ * @returns {void}
56
+ */
37
57
  export const recoverSnapshot = (log, req) => {
38
58
  log.debug(
39
59
  `Recovering snapshot for context '${req.casa.journeyContext.identity.id}'`,
@@ -45,9 +65,17 @@ export const recoverSnapshot = (log, req) => {
45
65
  deleteSnapshot(log, req);
46
66
  };
47
67
 
68
+ /**
69
+ * @param {CASADebugLogger} log Express request
70
+ * @param {ExpressRequest} req Express request
71
+ * @returns {void}
72
+ */
48
73
  export const deleteSnapshot = (log, req) => {
49
74
  log.debug(
50
75
  `Purging edit snapshot for context '${req.casa.journeyContext.identity.id}'`,
51
76
  );
52
77
  req.session[SESSION_KEY][req.casa.journeyContext.identity.id] = undefined;
53
78
  };
79
+
80
+ /** @typedef {import("../../../lib/logger.js").CASADebugLogger} CASADebugLogger */
81
+ /** @typedef {import("express").Request} ExpressRequest */
@@ -6,15 +6,15 @@
6
6
  * - Validation errors on that data
7
7
  * - Navigation information about how the user got where they are.
8
8
  */
9
- import lodash from "lodash";
9
+ import isPlainObject from "is-plain-obj";
10
+ import { deepEqual } from "fast-equals";
10
11
  import rfdc from "rfdc";
12
+ import NullObject from "./NullObject.js";
11
13
  import ValidationError from "./ValidationError.js";
12
14
  import logger from "./logger.js";
13
15
  import { notProto } from "./utils.js";
14
16
  import { uuid as uuidGenerator } from "./context-id-generators.js";
15
17
 
16
- const { isPlainObject, isObject, isEqual } = lodash; // CommonJS
17
-
18
18
  const log = logger("lib:journey-context");
19
19
 
20
20
  const uuid = uuidGenerator();
@@ -46,13 +46,18 @@ const clone = rfdc({ proto: false });
46
46
  * @access private
47
47
  */
48
48
 
49
+ /**
50
+ * @typedef {import("../casa").JourneyContextIdentity} JourneyContextIdentity
51
+ * @access private
52
+ */
53
+
49
54
  /**
50
55
  * @typedef {import("express").Request} ExpressRequest
51
56
  * @access private
52
57
  */
53
58
 
54
59
  /**
55
- * @param {any} key Object key to validate
60
+ * @param {string} key Object key to validate
56
61
  * @returns {string} Validated key
57
62
  */
58
63
  export function validateObjectKey(key = "") {
@@ -67,7 +72,7 @@ export function validateObjectKey(key = "") {
67
72
  return String(key);
68
73
  }
69
74
 
70
- /** @memberof module:@dwp/govuk-casa */
75
+ /** @memberof module:"@dwp/govuk-casa" */
71
76
  export default class JourneyContext {
72
77
  // Private properties
73
78
  #data;
@@ -109,10 +114,11 @@ export default class JourneyContext {
109
114
  * among a group of contexts stored in the session.
110
115
  *
111
116
  * @param {Record<string, any>} data Entire journey data.
112
- * @param {object} validation Page errors (indexed by waypoint id).
113
- * @param {object} nav Navigation context.
114
- * @param {object} identity Some metadata for identifying this context among
115
- * others.
117
+ * @param {Record<string, ValidationError[] | null>} validation Page errors
118
+ * (indexed by waypoint id).
119
+ * @param {{ language?: string }} nav Navigation context.
120
+ * @param {JourneyContextIdentity} identity Some metadata for identifying this
121
+ * context among others.
116
122
  */
117
123
  constructor(data = {}, validation = {}, nav = {}, identity = {}) {
118
124
  this.#data = data;
@@ -129,7 +135,7 @@ export default class JourneyContext {
129
135
  * @returns {JourneyContextObject} Plain object.
130
136
  */
131
137
  toObject() {
132
- return Object.assign(Object.create(null), {
138
+ return Object.assign(new NullObject(), {
133
139
  data: clone(this.#data),
134
140
  validation: clone(this.#validation),
135
141
  nav: clone(this.#nav),
@@ -144,14 +150,14 @@ export default class JourneyContext {
144
150
  * @returns {JourneyContext} Instance.
145
151
  */
146
152
  static fromObject({
147
- data = Object.create(null),
148
- validation = Object.create(null),
149
- nav = Object.create(null),
150
- identity = Object.create(null),
153
+ data = new NullObject(),
154
+ validation = new NullObject(),
155
+ nav = new NullObject(),
156
+ identity = new NullObject(),
151
157
  } = {}) {
152
158
  // As we're constructing a JourneyContext from a plain JS object, we need to
153
159
  // ensure any validation errors are instances of ValidationError.
154
- const deserialisedValidation = Object.create(null);
160
+ const deserialisedValidation = new NullObject();
155
161
  for (const [waypoint, errors] of Object.entries(validation)) {
156
162
  let dErrors = errors;
157
163
 
@@ -341,7 +347,7 @@ export default class JourneyContext {
341
347
  */
342
348
  getValidationErrorsForPageByField(pageId) {
343
349
  const errors = this.getValidationErrorsForPage(pageId);
344
- const obj = Object.create(null);
350
+ const obj = new NullObject();
345
351
 
346
352
  // ESLint disabled as `i` is an integer
347
353
  /* eslint-disable security/detect-object-injection */
@@ -394,8 +400,8 @@ export default class JourneyContext {
394
400
  * @param {string[]} waypoints Waypoints to be removed
395
401
  */
396
402
  purge(waypoints = []) {
397
- const newData = Object.create(null);
398
- const newValidation = Object.create(null);
403
+ const newData = new NullObject();
404
+ const newValidation = new NullObject();
399
405
  const toKeep = Object.keys(this.#data).filter(
400
406
  (w) => !waypoints.includes(w),
401
407
  );
@@ -483,12 +489,12 @@ export default class JourneyContext {
483
489
  logMessage = `Calling waypoint-specific event handler on "${waypoint}"`;
484
490
  runHandler =
485
491
  previousContext.data?.[waypoint] !== undefined &&
486
- !isEqual(this.data?.[waypoint], previousContext.data?.[waypoint]);
492
+ !deepEqual(this.data?.[waypoint], previousContext.data?.[waypoint]);
487
493
  } else if (waypoint && field) {
488
494
  logMessage = `Calling field-specific event handler on "${waypoint} : ${field}"`;
489
495
  runHandler =
490
496
  previousContext.data?.[waypoint]?.[field] !== undefined &&
491
- !isEqual(
497
+ !deepEqual(
492
498
  this.data?.[waypoint]?.[field],
493
499
  previousContext.data?.[waypoint]?.[field],
494
500
  );
@@ -773,7 +779,7 @@ export default class JourneyContext {
773
779
  * @throws {TypeError} When session is not a valid type, or context has no ID
774
780
  */
775
781
  static putContext(session, context, options = {}) {
776
- if (!isObject(session)) {
782
+ if (typeof session !== "object" || session === null) {
777
783
  throw new TypeError("Session must be an object");
778
784
  } else if (!(context instanceof JourneyContext)) {
779
785
  throw new TypeError("Context must be a valid JourneyContext");
@@ -933,20 +939,17 @@ export default class JourneyContext {
933
939
  /* eslint-disable security/detect-object-injection */
934
940
  // Unset, with setSkipped(a, false)
935
941
  if (opts === false) {
936
- this.data[waypoint] ??= Object.create(null);
937
- this.data[waypoint].__skipped__ = undefined;
942
+ this.data[waypoint] ??= new NullObject();
938
943
  this.data[waypoint].__skip__ = undefined;
939
944
  }
940
945
  // Set, with setSkipped(a, true) and clear data
941
946
  else if (opts === true) {
942
- this.data[waypoint] = Object.create(null);
943
- this.data[waypoint].__skipped__ = true;
947
+ this.data[waypoint] = new NullObject();
944
948
  this.data[waypoint].__skip__ = { to: null };
945
949
  }
946
950
  // Set, with setSkipped(a, { to: b }) and clear data
947
951
  else if (typeof opts?.to === "string") {
948
- this.data[waypoint] = Object.create(null);
949
- this.data[waypoint].__skipped__ = true;
952
+ this.data[waypoint] = new NullObject();
950
953
  this.data[waypoint].__skip__ = { to: opts.to };
951
954
  } else {
952
955
  throw new TypeError(
@@ -969,7 +972,7 @@ export default class JourneyContext {
969
972
  const wpData = this.data[String(waypoint)];
970
973
 
971
974
  if (opts === undefined) {
972
- return wpData?.__skipped__ === true || wpData?.__skip__ !== undefined;
975
+ return wpData?.__skip__ !== undefined;
973
976
  } else if (typeof opts.to === "string") {
974
977
  return wpData?.__skip__?.to === opts.to;
975
978
  }
@@ -1,8 +1,8 @@
1
1
  import { Router } from "express";
2
2
 
3
- /** @memberof module:@dwp/govuk-casa */
3
+ /** @memberof module:"@dwp/govuk-casa" */
4
4
  export default class MutableRouter {
5
- /** @type {Array} */
5
+ /** @type {StackRoute[]} */
6
6
  #stack;
7
7
 
8
8
  /** @type {Router} */
@@ -100,8 +100,8 @@ export default class MutableRouter {
100
100
  /**
101
101
  * Prepend middleware function(s) using the `all()` method.
102
102
  *
103
- * @param {string | Function} path Route path or middleware function
104
- * @param {...Function} callbacks Additional middleware functions
103
+ * @param {string | RequestHandler} path Route path or middleware function
104
+ * @param {...RequestHandler} callbacks Additional middleware functions
105
105
  * @returns {void}
106
106
  */
107
107
  prependAll(path, ...callbacks) {
@@ -111,8 +111,8 @@ export default class MutableRouter {
111
111
  /**
112
112
  * Prepend middleware function(s) using the `get()` method.
113
113
  *
114
- * @param {string | Function} path Route path or middleware function
115
- * @param {...Function} callbacks Additional middleware functions
114
+ * @param {string | RequestHandler} path Route path or middleware function
115
+ * @param {...RequestHandler} callbacks Additional middleware functions
116
116
  * @returns {void}
117
117
  */
118
118
  prependGet(path, ...callbacks) {
@@ -122,8 +122,8 @@ export default class MutableRouter {
122
122
  /**
123
123
  * Prepend middleware function(s) using the `post()` method.
124
124
  *
125
- * @param {string | Function} path Route path or middleware function
126
- * @param {...Function} callbacks Additional middleware functions
125
+ * @param {string | RequestHandler} path Route path or middleware function
126
+ * @param {...RequestHandler} callbacks Additional middleware functions
127
127
  * @returns {void}
128
128
  */
129
129
  prependPost(path, ...callbacks) {
@@ -133,8 +133,8 @@ export default class MutableRouter {
133
133
  /**
134
134
  * Prepend middleware function(s) using the `delete()` method.
135
135
  *
136
- * @param {string | Function} path Route path or middleware function
137
- * @param {...Function} callbacks Additional middleware functions
136
+ * @param {string | RequestHandler} path Route path or middleware function
137
+ * @param {...RequestHandler} callbacks Additional middleware functions
138
138
  * @returns {void}
139
139
  */
140
140
  prependDelete(path, ...callbacks) {
@@ -144,8 +144,8 @@ export default class MutableRouter {
144
144
  /**
145
145
  * Prepend middleware function(s) using the `put()` method.
146
146
  *
147
- * @param {string | Function} path Route path or middleware function
148
- * @param {...Function} callbacks Additional middleware functions
147
+ * @param {string | RequestHandler} path Route path or middleware function
148
+ * @param {...RequestHandler} callbacks Additional middleware functions
149
149
  * @returns {void}
150
150
  */
151
151
  prependPut(path, ...callbacks) {
@@ -155,8 +155,8 @@ export default class MutableRouter {
155
155
  /**
156
156
  * Prepend middleware function(s) using the `use()` method.
157
157
  *
158
- * @param {string | Function} path Route path or middleware function
159
- * @param {...Function} callbacks Additional middleware functions
158
+ * @param {string | RequestHandler} path Route path or middleware function
159
+ * @param {...RequestHandler} callbacks Additional middleware functions
160
160
  * @returns {void}
161
161
  */
162
162
  prependUse(path, ...callbacks) {
@@ -168,8 +168,8 @@ export default class MutableRouter {
168
168
  /**
169
169
  * Replace middleware function(s) that were mounted using the `all()` method.
170
170
  *
171
- * @param {string | Function} path Route path or middleware function
172
- * @param {...Function} callbacks Additional middleware functions
171
+ * @param {string | RequestHandler} path Route path or middleware function
172
+ * @param {...RequestHandler} callbacks Additional middleware functions
173
173
  * @returns {void}
174
174
  */
175
175
  replaceAll(path, ...callbacks) {
@@ -179,8 +179,8 @@ export default class MutableRouter {
179
179
  /**
180
180
  * Replace middleware function(s) that were mounted using the `get()` method.
181
181
  *
182
- * @param {string | Function} path Route path or middleware function
183
- * @param {...Function} callbacks Additional middleware functions
182
+ * @param {string | RequestHandler} path Route path or middleware function
183
+ * @param {...RequestHandler} callbacks Additional middleware functions
184
184
  * @returns {void}
185
185
  */
186
186
  replaceGet(path, ...callbacks) {
@@ -190,8 +190,8 @@ export default class MutableRouter {
190
190
  /**
191
191
  * Replace middleware function(s) that were mounted using the `post()` method.
192
192
  *
193
- * @param {string | Function} path Route path or middleware function
194
- * @param {...Function} callbacks Additional middleware functions
193
+ * @param {string | RequestHandler} path Route path or middleware function
194
+ * @param {...RequestHandler} callbacks Additional middleware functions
195
195
  * @returns {void}
196
196
  */
197
197
  replacePost(path, ...callbacks) {
@@ -202,8 +202,8 @@ export default class MutableRouter {
202
202
  * Replace middleware function(s) that were mounted using the `delete()`
203
203
  * method.
204
204
  *
205
- * @param {string | Function} path Route path or middleware function
206
- * @param {...Function} callbacks Additional middleware functions
205
+ * @param {string | RequestHandler} path Route path or middleware function
206
+ * @param {...RequestHandler} callbacks Additional middleware functions
207
207
  * @returns {void}
208
208
  */
209
209
  replaceDelete(path, ...callbacks) {
@@ -213,8 +213,8 @@ export default class MutableRouter {
213
213
  /**
214
214
  * Replace middleware function(s) that were mounted using the `put()` method.
215
215
  *
216
- * @param {string | Function} path Route path or middleware function
217
- * @param {...Function} callbacks Additional middleware functions
216
+ * @param {string | RequestHandler} path Route path or middleware function
217
+ * @param {...RequestHandler} callbacks Additional middleware functions
218
218
  * @returns {void}
219
219
  */
220
220
  replacePut(path, ...callbacks) {
@@ -224,8 +224,8 @@ export default class MutableRouter {
224
224
  /**
225
225
  * Replace middleware function(s) that were mounted using the `use()` method.
226
226
  *
227
- * @param {string | Function} path Route path or middleware function
228
- * @param {...Function} callbacks Additional middleware functions
227
+ * @param {string | RequestHandler} path Route path or middleware function
228
+ * @param {...RequestHandler} callbacks Additional middleware functions
229
229
  * @returns {void}
230
230
  */
231
231
  replaceUse(path, ...callbacks) {
@@ -237,8 +237,8 @@ export default class MutableRouter {
237
237
  /**
238
238
  * Append middleware function(s) using the `all()` method.
239
239
  *
240
- * @param {string | Function} path Route path or middleware function
241
- * @param {...Function} callbacks Additional middleware functions
240
+ * @param {string | RequestHandler} path Route path or middleware function
241
+ * @param {...RequestHandler} callbacks Additional middleware functions
242
242
  * @returns {void}
243
243
  */
244
244
  all(path, ...callbacks) {
@@ -248,8 +248,8 @@ export default class MutableRouter {
248
248
  /**
249
249
  * Append middleware function(s) using the `get()` method.
250
250
  *
251
- * @param {string | Function} path Route path or middleware function
252
- * @param {...Function} callbacks Additional middleware functions
251
+ * @param {string | RequestHandler} path Route path or middleware function
252
+ * @param {...RequestHandler} callbacks Additional middleware functions
253
253
  * @returns {void}
254
254
  */
255
255
  get(path, ...callbacks) {
@@ -259,8 +259,8 @@ export default class MutableRouter {
259
259
  /**
260
260
  * Append middleware function(s) using the `post()` method.
261
261
  *
262
- * @param {string | Function} path Route path or middleware function
263
- * @param {...Function} callbacks Additional middleware functions
262
+ * @param {string | RequestHandler} path Route path or middleware function
263
+ * @param {...RequestHandler} callbacks Additional middleware functions
264
264
  * @returns {void}
265
265
  */
266
266
  post(path, ...callbacks) {
@@ -270,8 +270,8 @@ export default class MutableRouter {
270
270
  /**
271
271
  * Append middleware function(s) using the `delete()` method.
272
272
  *
273
- * @param {string | Function} path Route path or middleware function
274
- * @param {...Function} callbacks Additional middleware functions
273
+ * @param {string | RequestHandler} path Route path or middleware function
274
+ * @param {...RequestHandler} callbacks Additional middleware functions
275
275
  * @returns {void}
276
276
  */
277
277
  delete(path, ...callbacks) {
@@ -281,8 +281,8 @@ export default class MutableRouter {
281
281
  /**
282
282
  * Append middleware function(s) using the `put()` method.
283
283
  *
284
- * @param {string | Function} path Route path or middleware function
285
- * @param {...Function} callbacks Additional middleware functions
284
+ * @param {string | RequestHandler} path Route path or middleware function
285
+ * @param {...RequestHandler} callbacks Additional middleware functions
286
286
  * @returns {void}
287
287
  */
288
288
  put(path, ...callbacks) {
@@ -292,8 +292,8 @@ export default class MutableRouter {
292
292
  /**
293
293
  * Append middleware function(s) using the `use()` method.
294
294
  *
295
- * @param {string | Function} path Route path or middleware function
296
- * @param {...Function} callbacks Additional middleware functions
295
+ * @param {string | RequestHandler} path Route path or middleware function
296
+ * @param {...RequestHandler} callbacks Additional middleware functions
297
297
  * @returns {void}
298
298
  */
299
299
  use(path, ...callbacks) {
@@ -306,3 +306,12 @@ export default class MutableRouter {
306
306
  );
307
307
  }
308
308
  }
309
+
310
+ /** @typedef {import("express").RequestHandler} RequestHandler */
311
+
312
+ /**
313
+ * @typedef {object} StackRoute Stack route
314
+ * @property {string} method HTTP request method
315
+ * @property {string} path Route path
316
+ * @property {[string, ...RequestHandler[]]} args Router arguments
317
+ */
@@ -0,0 +1,4 @@
1
+ const NullObject = function () {};
2
+ NullObject.prototype = Object.create(null);
3
+
4
+ export default NullObject;