@dwp/govuk-casa 9.3.3 → 9.3.5

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 (89) hide show
  1. package/dist/assets/css/casa.css +1 -1
  2. package/dist/assets/css/casa.css.map +1 -1
  3. package/dist/lib/CasaTemplateLoader.js +22 -28
  4. package/dist/lib/CasaTemplateLoader.js.map +1 -1
  5. package/dist/lib/JourneyContext.js +86 -112
  6. package/dist/lib/JourneyContext.js.map +1 -1
  7. package/dist/lib/MutableRouter.js +71 -80
  8. package/dist/lib/MutableRouter.js.map +1 -1
  9. package/dist/lib/Plan.js +15 -26
  10. package/dist/lib/Plan.js.map +1 -1
  11. package/dist/lib/ValidationError.js +3 -3
  12. package/dist/lib/ValidationError.js.map +1 -1
  13. package/dist/lib/configuration-ingestor.js +21 -10
  14. package/dist/lib/configuration-ingestor.js.map +1 -1
  15. package/dist/lib/configure.js +18 -17
  16. package/dist/lib/configure.js.map +1 -1
  17. package/dist/lib/end-session.js +5 -5
  18. package/dist/lib/end-session.js.map +1 -1
  19. package/dist/lib/field.js +56 -65
  20. package/dist/lib/field.js.map +1 -1
  21. package/dist/lib/nunjucks-filters.js +6 -6
  22. package/dist/lib/nunjucks-filters.js.map +1 -1
  23. package/dist/lib/nunjucks.js +3 -3
  24. package/dist/lib/nunjucks.js.map +1 -1
  25. package/dist/lib/utils.js +6 -1
  26. package/dist/lib/utils.js.map +1 -1
  27. package/dist/lib/validators/dateObject.js +23 -14
  28. package/dist/lib/validators/dateObject.js.map +1 -1
  29. package/dist/lib/validators/email.js +2 -5
  30. package/dist/lib/validators/email.js.map +1 -1
  31. package/dist/lib/validators/inArray.js +2 -5
  32. package/dist/lib/validators/inArray.js.map +1 -1
  33. package/dist/lib/validators/nino.js +1 -4
  34. package/dist/lib/validators/nino.js.map +1 -1
  35. package/dist/lib/validators/postalAddressObject.js +26 -19
  36. package/dist/lib/validators/postalAddressObject.js.map +1 -1
  37. package/dist/lib/validators/range.js +2 -6
  38. package/dist/lib/validators/range.js.map +1 -1
  39. package/dist/lib/validators/regex.js +1 -4
  40. package/dist/lib/validators/regex.js.map +1 -1
  41. package/dist/lib/validators/required.js +1 -4
  42. package/dist/lib/validators/required.js.map +1 -1
  43. package/dist/lib/validators/strlen.js +1 -4
  44. package/dist/lib/validators/strlen.js.map +1 -1
  45. package/dist/lib/validators/wordCount.js +1 -4
  46. package/dist/lib/validators/wordCount.js.map +1 -1
  47. package/dist/middleware/csrf.js +4 -2
  48. package/dist/middleware/csrf.js.map +1 -1
  49. package/dist/middleware/data.js +17 -10
  50. package/dist/middleware/data.js.map +1 -1
  51. package/dist/middleware/i18n.d.ts +1 -1
  52. package/dist/middleware/i18n.js +16 -16
  53. package/dist/middleware/i18n.js.map +1 -1
  54. package/dist/middleware/post.js +9 -7
  55. package/dist/middleware/post.js.map +1 -1
  56. package/dist/middleware/pre.js +2 -2
  57. package/dist/middleware/pre.js.map +1 -1
  58. package/dist/middleware/sanitise-fields.d.ts +1 -1
  59. package/dist/middleware/sanitise-fields.js +1 -2
  60. package/dist/middleware/sanitise-fields.js.map +1 -1
  61. package/dist/middleware/session.js +11 -6
  62. package/dist/middleware/session.js.map +1 -1
  63. package/dist/middleware/strip-proxy-path.js +1 -2
  64. package/dist/middleware/strip-proxy-path.js.map +1 -1
  65. package/dist/middleware/validate-fields.d.ts +1 -1
  66. package/dist/middleware/validate-fields.js +1 -2
  67. package/dist/middleware/validate-fields.js.map +1 -1
  68. package/dist/routes/journey.js +15 -11
  69. package/dist/routes/journey.js.map +1 -1
  70. package/dist/routes/static.js +8 -9
  71. package/dist/routes/static.js.map +1 -1
  72. package/package.json +24 -23
  73. package/src/lib/JourneyContext.js +22 -19
  74. package/src/lib/MutableRouter.js +2 -2
  75. package/src/lib/Plan.js +2 -8
  76. package/src/lib/ValidationError.js +2 -2
  77. package/src/lib/configuration-ingestor.js +21 -12
  78. package/src/lib/configure.js +14 -11
  79. package/src/lib/end-session.js +5 -5
  80. package/src/lib/nunjucks-filters.js +6 -6
  81. package/src/lib/nunjucks.js +2 -2
  82. package/src/lib/validators/dateObject.js +5 -5
  83. package/src/lib/validators/postalAddressObject.js +8 -10
  84. package/src/middleware/data.js +4 -7
  85. package/src/middleware/i18n.js +9 -9
  86. package/src/middleware/pre.js +1 -1
  87. package/src/middleware/sanitise-fields.js +1 -2
  88. package/src/routes/journey.js +2 -2
  89. package/src/routes/static.js +4 -4
@@ -5,10 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = staticRouter;
7
7
  const express_1 = __importDefault(require("express"));
8
- const fs_1 = require("fs");
9
- const url_1 = require("url");
10
- const path_1 = require("path");
11
- const module_1 = require("module");
8
+ const node_fs_1 = require("node:fs");
9
+ const node_url_1 = require("node:url");
10
+ const node_path_1 = require("node:path");
11
+ const node_module_1 = require("node:module");
12
12
  const dirname_cjs_1 = __importDefault(require("./dirname.cjs"));
13
13
  const MutableRouter_js_1 = __importDefault(require("../lib/MutableRouter.js"));
14
14
  const utils_js_1 = require("../lib/utils.js");
@@ -33,11 +33,10 @@ function staticRouter({ maxAge = 3600000 } = {}) {
33
33
  next(new Error("404"));
34
34
  };
35
35
  const setHeaders = (req, res, next) => {
36
- var _a;
37
36
  res.set("cache-control", "public");
38
37
  res.set("pragma", "cache");
39
38
  res.set("expires", new Date(Date.now() + oneDay).toUTCString());
40
- const { pathname } = new url_1.URL((_a = req === null || req === void 0 ? void 0 : req.originalUrl) !== null && _a !== void 0 ? _a : "", "https://placeholder.test/");
39
+ const { pathname } = new node_url_1.URL(req?.originalUrl ?? "", "https://placeholder.test/");
41
40
  if (pathname.substr(-4) === ".css") {
42
41
  // Just needed for our in-memory CSS assets
43
42
  res.set("content-type", "text/css");
@@ -56,17 +55,17 @@ function staticRouter({ maxAge = 3600000 } = {}) {
56
55
  // must be replaced with the dynamic `mountUrl` to ensure govuk-frontend
57
56
  // assets are served from the correct location.
58
57
  /* eslint-disable security/detect-non-literal-fs-filename */
59
- const casaCss = (0, fs_1.readFileSync)((0, path_1.resolve)(dirname_cjs_1.default, "../../dist/assets/css/casa.css"), { encoding: "utf8" });
58
+ const casaCss = (0, node_fs_1.readFileSync)((0, node_path_1.resolve)(dirname_cjs_1.default, "../../dist/assets/css/casa.css"), { encoding: "utf8" });
60
59
  /* eslint-enable security/detect-non-literal-fs-filename */
61
60
  // The static middleware will only server GET/HEAD requests, so we can mount
62
61
  // the middleware using `use()` rather than resorting to `get()`
63
- const govukFrontendDirectory = (0, path_1.resolve)((0, module_1.createRequire)(dirname_cjs_1.default).resolve("govuk-frontend"), "../../");
62
+ const govukFrontendDirectory = (0, node_path_1.resolve)((0, node_module_1.createRequire)(dirname_cjs_1.default).resolve("govuk-frontend"), "../../");
64
63
  router.use("/govuk/govuk-frontend.min.js", ExpressStatic(`${govukFrontendDirectory}/govuk/govuk-frontend.min.js`, staticConfig));
65
64
  router.use("/govuk/govuk-frontend.min.js.map", ExpressStatic(`${govukFrontendDirectory}/govuk/govuk-frontend.min.js.map`, staticConfig));
66
65
  router.use("/govuk/assets", ExpressStatic(`${govukFrontendDirectory}/govuk/assets`, staticConfig));
67
66
  router.use("/govuk/assets", notFoundHandler);
68
67
  router.get("/casa/assets/css/casa.css", setHeaders, (req, res) => res.send(casaCss.replace(/~~~CASA_MOUNT_URL~~~/g, (0, utils_js_1.validateUrlPath)(`${req.baseUrl}/`))));
69
- router.use("/casa/assets/css/casa.css.map", ExpressStatic((0, path_1.resolve)(dirname_cjs_1.default, "../../dist/assets/css/casa.css.map")));
68
+ router.use("/casa/assets/css/casa.css.map", ExpressStatic((0, node_path_1.resolve)(dirname_cjs_1.default, "../../dist/assets/css/casa.css.map")));
70
69
  router.use("/casa/assets", notFoundHandler);
71
70
  return router;
72
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"static.js","sourceRoot":"","sources":["../../src/routes/static.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"static.js","sourceRoot":"","sources":["../../src/routes/static.js"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dwp/govuk-casa",
3
- "version": "9.3.3",
3
+ "version": "9.3.5",
4
4
  "description": "A framework for building GOVUK Collect-And-Submit-Applications",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,7 +20,7 @@
20
20
  "views/**/*"
21
21
  ],
22
22
  "engines": {
23
- "node": "^18.0.0 || ^20.0.0",
23
+ "node": "^18.0.0 || ^20.0.0 || ^22.0.0",
24
24
  "npm": "^8.0.0 || ^9.0.0 || ^10.0.0"
25
25
  },
26
26
  "scripts": {
@@ -56,49 +56,50 @@
56
56
  "deepmerge": "4.3.1",
57
57
  "express": "4.21.1",
58
58
  "express-session": "1.18.1",
59
- "govuk-frontend": "5.7.0",
60
- "helmet": "7.1.0",
61
- "i18next": "23.15.2",
59
+ "govuk-frontend": "5.7.1",
60
+ "helmet": "7.2.0",
61
+ "i18next": "23.16.5",
62
62
  "i18next-http-middleware": "3.6.0",
63
63
  "js-yaml": "4.1.0",
64
64
  "lodash": "4.17.21",
65
65
  "luxon": "3.5.0",
66
66
  "nunjucks": "3.2.4",
67
67
  "path-to-regexp": "8.2.0",
68
+ "rfdc": "1.4.1",
68
69
  "validator": "13.12.0"
69
70
  },
70
71
  "devDependencies": {
71
- "@babel/core": "7.25.2",
72
- "@babel/eslint-parser": "7.25.1",
73
- "@babel/preset-env": "7.25.4",
72
+ "@babel/core": "7.26.0",
73
+ "@babel/eslint-parser": "7.25.9",
74
+ "@babel/preset-env": "7.26.0",
74
75
  "@ckeditor/jsdoc-plugins": "42.1.0",
75
- "@commitlint/config-conventional": "19.4.1",
76
- "@dwp/casa-spiderplan": "4.0.0",
77
- "@dwp/casa-spiderplan-a11y-plugin": "1.0.0",
76
+ "@commitlint/config-conventional": "19.5.0",
77
+ "@dwp/casa-spiderplan": "4.0.2",
78
+ "@dwp/casa-spiderplan-a11y-plugin": "1.0.1",
78
79
  "@dwp/casa-spiderplan-zap-plugin": "1.0.0",
79
80
  "@dwp/eslint-config-base": "7.0.0",
80
81
  "@types/express": "4.17.21",
81
- "@types/node": "22.5.4",
82
+ "@types/node": "22.9.0",
82
83
  "@types/nunjucks": "3.2.6",
83
84
  "c8": "10.1.2",
84
- "chai": "5.1.1",
85
+ "chai": "5.1.2",
85
86
  "cheerio": "1.0.0",
86
- "commitlint": "19.3.0",
87
+ "commitlint": "19.5.0",
87
88
  "docdash": "2.0.2",
88
- "eslint": "8.57.0",
89
- "eslint-plugin-import": "2.30.0",
90
- "eslint-plugin-jsdoc": "48.7.0",
89
+ "eslint": "8.57.1",
90
+ "eslint-plugin-import": "2.31.0",
91
+ "eslint-plugin-jsdoc": "48.11.0",
91
92
  "eslint-plugin-security": "2.1.1",
92
93
  "eslint-plugin-sonarjs": "0.25.1",
93
- "fast-check": "3.22.0",
94
- "jsdoc": "4.0.3",
94
+ "fast-check": "3.23.1",
95
+ "jsdoc": "4.0.4",
95
96
  "jsdoc-tsimport-plugin": "1.0.5",
96
- "mocha": "10.7.3",
97
+ "mocha": "10.8.2",
97
98
  "prettier": "3.3.3",
98
99
  "prettier-plugin-jsdoc": "1.3.0",
99
- "sass": "1.78.0",
100
- "sinon": "18.0.0",
100
+ "sass": "1.81.0",
101
+ "sinon": "18.0.1",
101
102
  "supertest": "7.0.0",
102
- "typescript": "5.5.4"
103
+ "typescript": "5.6.3"
103
104
  }
104
105
  }
@@ -7,17 +7,20 @@
7
7
  * - Navigation information about how the user got where they are.
8
8
  */
9
9
  import lodash from "lodash";
10
+ import rfdc from "rfdc";
10
11
  import ValidationError from "./ValidationError.js";
11
12
  import logger from "./logger.js";
12
13
  import { notProto } from "./utils.js";
13
14
  import { uuid as uuidGenerator } from "./context-id-generators.js";
14
15
 
15
- const { isPlainObject, isObject, has, isEqual } = lodash; // CommonJS
16
+ const { isPlainObject, isObject, isEqual } = lodash; // CommonJS
16
17
 
17
18
  const log = logger("lib:journey-context");
18
19
 
19
20
  const uuid = uuidGenerator();
20
21
 
22
+ const clone = rfdc({ proto: false });
23
+
21
24
  /**
22
25
  * @typedef {import("../casa").ContextEventUserInfo} ContextEventUserInfo
23
26
  * @access private
@@ -123,10 +126,10 @@ export default class JourneyContext {
123
126
  */
124
127
  toObject() {
125
128
  return Object.assign(Object.create(null), {
126
- data: structuredClone(this.#data),
127
- validation: structuredClone(this.#validation),
128
- nav: structuredClone(this.#nav),
129
- identity: structuredClone(this.#identity),
129
+ data: clone(this.#data),
130
+ validation: clone(this.#validation),
131
+ nav: clone(this.#nav),
132
+ identity: clone(this.#identity),
130
133
  });
131
134
  }
132
135
 
@@ -294,11 +297,11 @@ export default class JourneyContext {
294
297
  );
295
298
  }
296
299
 
297
- errors.forEach((error) => {
300
+ for (const error of errors) {
298
301
  if (!(error instanceof ValidationError)) {
299
302
  throw new SyntaxError("Field errors must be a ValidationError");
300
303
  }
301
- });
304
+ }
302
305
 
303
306
  this.#validation[validateObjectKey(pageId)] = errors;
304
307
 
@@ -562,7 +565,7 @@ export default class JourneyContext {
562
565
  }
563
566
 
564
567
  // Initialise new context list in the session
565
- if (!has(session, "journeyContextList")) {
568
+ if (!Object.hasOwn(session, "journeyContextList")) {
566
569
  log.trace("Initialising session with a default journey context list");
567
570
  /* eslint-disable-next-line no-param-reassign */
568
571
  session.journeyContextList = [];
@@ -738,7 +741,7 @@ export default class JourneyContext {
738
741
  * @returns {Array} Array of contexts
739
742
  */
740
743
  static getContexts(session) {
741
- if (has(session, "journeyContextList")) {
744
+ if (session && Object.hasOwn(session, "journeyContextList")) {
742
745
  return session.journeyContextList.map(([, contextObj]) =>
743
746
  JourneyContext.fromObject(contextObj),
744
747
  );
@@ -768,7 +771,7 @@ export default class JourneyContext {
768
771
  }
769
772
 
770
773
  // Initialise the session if necessary
771
- if (!has(session, "journeyContextList")) {
774
+ if (Object.hasOwn(session, "journeyContextList") === false) {
772
775
  JourneyContext.initContextStore(session);
773
776
  }
774
777
 
@@ -844,9 +847,9 @@ export default class JourneyContext {
844
847
  * @returns {void}
845
848
  */
846
849
  static removeContextsByTag(session, tag) {
847
- JourneyContext.getContextsByTag(session, tag).forEach((c) =>
848
- JourneyContext.removeContext(session, c),
849
- );
850
+ for (const c of JourneyContext.getContextsByTag(session, tag)) {
851
+ JourneyContext.removeContext(session, c);
852
+ }
850
853
  }
851
854
 
852
855
  /**
@@ -856,9 +859,9 @@ export default class JourneyContext {
856
859
  * @returns {void}
857
860
  */
858
861
  static removeContexts(session) {
859
- JourneyContext.getContexts(session).forEach((c) =>
860
- JourneyContext.removeContext(session, c),
861
- );
862
+ for (const c of JourneyContext.getContexts(session)) {
863
+ JourneyContext.removeContext(session, c);
864
+ }
862
865
  }
863
866
 
864
867
  /**
@@ -875,13 +878,13 @@ export default class JourneyContext {
875
878
  JourneyContext.initContextStore(req.session);
876
879
 
877
880
  let contextId;
878
- if (has(req?.params, "contextid")) {
881
+ if (req.params && Object.hasOwn(req.params, "contextid")) {
879
882
  log.trace("Context ID found in req.params.contextid");
880
883
  contextId = String(req.params.contextid);
881
- } else if (has(req.query, "contextid")) {
884
+ } else if (req.query && Object.hasOwn(req.query, "contextid")) {
882
885
  log.trace("Context ID found in req.query.contextid");
883
886
  contextId = String(req.query.contextid);
884
- } else if (has(req?.body, "contextid")) {
887
+ } else if (req.body && Object.hasOwn(req.body, "contextid")) {
885
888
  log.trace("Context ID found in req.body.contextid");
886
889
  contextId = String(req.body.contextid);
887
890
  } else {
@@ -84,12 +84,12 @@ export default class MutableRouter {
84
84
  return this.#router;
85
85
  }
86
86
 
87
- this.#stack.forEach(({ method, args }) => {
87
+ for (const { method, args } of this.#stack) {
88
88
  // ESLint disabled as `#router` is dev-controlled, and `seal()` is only
89
89
  // run at boot-time before any user interaction
90
90
  /* eslint-disable-next-line security/detect-object-injection */
91
91
  this.#router[method].call(this.#router, ...args);
92
- });
92
+ }
93
93
 
94
94
  this.#sealed = true;
95
95
 
package/src/lib/Plan.js CHANGED
@@ -40,10 +40,7 @@ const log = logger("lib:plan");
40
40
  * @access private
41
41
  */
42
42
  function defaultNextFollow(r, context) {
43
- const { validation: v = {} } = context.toObject();
44
- return (
45
- Object.prototype.hasOwnProperty.call(v, r.source) && v[r.source] === null
46
- );
43
+ return context.validation?.[r.source] === null;
47
44
  }
48
45
 
49
46
  /**
@@ -54,10 +51,7 @@ function defaultNextFollow(r, context) {
54
51
  * @access private
55
52
  */
56
53
  function defaultPrevFollow(r, context) {
57
- const { validation: v = {} } = context.toObject();
58
- return (
59
- Object.prototype.hasOwnProperty.call(v, r.target) && v[r.target] === null
60
- );
54
+ return context.validation?.[r.target] === null;
61
55
  }
62
56
 
63
57
  /**
@@ -113,7 +113,7 @@ export default class ValidationError {
113
113
  // Duplicate parameters to make them available in public scope. These are
114
114
  // the values that will be readable, and reflect any context that may have
115
115
  // been applied
116
- Object.keys(originals).forEach((o) => {
116
+ for (const o of Object.keys(originals)) {
117
117
  // ESLint disabled as `o` is an "own" property of `originals`, which is
118
118
  // dev-controlled
119
119
  /* eslint-disable security/detect-object-injection */
@@ -123,7 +123,7 @@ export default class ValidationError {
123
123
  writable: true,
124
124
  });
125
125
  /* eslint-enable security/detect-object-injection */
126
- });
126
+ }
127
127
  }
128
128
 
129
129
  /**
@@ -58,13 +58,14 @@ export function validateI18nDirs(dirs = []) {
58
58
  if (!Array.isArray(dirs)) {
59
59
  throw new TypeError("I18n directories must be an array (i18n.dirs)");
60
60
  }
61
- dirs.forEach((dir, i) => {
61
+ for (let i = 0; i < dirs.length; i++) {
62
+ const dir = dirs[i];
62
63
  if (typeof dir !== "string") {
63
64
  throw new TypeError(
64
65
  `I18n directory must be a string, got ${typeof dir} (i18n.dirs[${i}])`,
65
66
  );
66
67
  }
67
- });
68
+ }
68
69
  return dirs;
69
70
  }
70
71
 
@@ -81,13 +82,14 @@ export function validateI18nLocales(locales = ["en", "cy"]) {
81
82
  if (!Array.isArray(locales)) {
82
83
  throw new TypeError("I18n locales must be an array (i18n.locales)");
83
84
  }
84
- locales.forEach((locale, i) => {
85
+ for (let i = 0; i < locales.length; i++) {
86
+ const locale = locales[i];
85
87
  if (typeof locale !== "string") {
86
88
  throw new TypeError(
87
89
  `I18n locale must be a string, got ${typeof locale} (i18n.locales[${i}])`,
88
90
  );
89
91
  }
90
- });
92
+ }
91
93
  return locales;
92
94
  }
93
95
 
@@ -146,13 +148,14 @@ export function validateViews(dirs = []) {
146
148
  if (!Array.isArray(dirs)) {
147
149
  throw new TypeError("View directories must be an array (views)");
148
150
  }
149
- dirs.forEach((dir, i) => {
151
+ for (let i = 0; i < dirs.length; i++) {
152
+ const dir = dirs[i];
150
153
  if (typeof dir !== "string") {
151
154
  throw new TypeError(
152
155
  `View directory must be a string, got ${typeof dir} (views[${i}])`,
153
156
  );
154
157
  }
155
- });
158
+ }
156
159
  return dirs;
157
160
  }
158
161
 
@@ -336,7 +339,9 @@ export function validatePageHooks(hooks) {
336
339
  if (!Array.isArray(hooks)) {
337
340
  throw new TypeError("Hooks must be an array");
338
341
  }
339
- hooks.forEach((hook, index) => validatePageHook(hook, index));
342
+ for (let i = 0; i < hooks.length; i++) {
343
+ validatePageHook(hooks[i], i);
344
+ }
340
345
  return hooks;
341
346
  }
342
347
 
@@ -357,7 +362,9 @@ export function validateFields(fields) {
357
362
  if (!Array.isArray(fields)) {
358
363
  throw new TypeError("Page fields must be an array (page[].fields)");
359
364
  }
360
- fields.forEach((hook, index) => validateField(hook, index));
365
+ for (let i = 0; i < fields.length; i++) {
366
+ validateField(fields[i], i);
367
+ }
361
368
  return fields;
362
369
  }
363
370
 
@@ -384,7 +391,9 @@ export function validatePages(pages = []) {
384
391
  if (!Array.isArray(pages)) {
385
392
  throw new TypeError("Pages must be an array (pages)");
386
393
  }
387
- pages.forEach((page, index) => validatePage(page, index));
394
+ for (let i = 0; i < pages.length; i++) {
395
+ validatePage(pages[i], i);
396
+ }
388
397
  return pages;
389
398
  }
390
399
 
@@ -419,12 +428,12 @@ export function validateGlobalHooks(hooks) {
419
428
  if (hooks === undefined) {
420
429
  return [];
421
430
  }
422
-
423
431
  if (!Array.isArray(hooks)) {
424
432
  throw new TypeError("Hooks must be an array");
425
433
  }
426
-
427
- hooks.forEach((hook, index) => validateGlobalHook(hook, index));
434
+ for (let i = 0; i < hooks.length; i++) {
435
+ validateGlobalHook(hooks[i], i);
436
+ }
428
437
  return hooks;
429
438
  }
430
439
 
@@ -1,6 +1,6 @@
1
1
  import { MemoryStore } from "express-session";
2
- import { resolve } from "path";
3
- import { createRequire } from "module";
2
+ import { resolve } from "node:path";
3
+ import { createRequire } from "node:module";
4
4
  import cookieParserFactory from "cookie-parser";
5
5
  import dirname from "./dirname.cjs";
6
6
 
@@ -49,9 +49,9 @@ import { CONFIG_ERROR_VISIBILITY_ONSUBMIT } from "./constants.js";
49
49
  export default function configure(config = {}) {
50
50
  // Pass the raw config through each plugin's configure phase so they can
51
51
  // optionally modify it
52
- (config.plugins ?? []).forEach((plugin) => {
52
+ for (const plugin of config.plugins ?? []) {
53
53
  plugin.configure(config);
54
- });
54
+ }
55
55
 
56
56
  // Extract config
57
57
  const ingestedConfig = configurationIngestor(config);
@@ -84,10 +84,13 @@ export default function configure(config = {}) {
84
84
  } = ingestedConfig;
85
85
 
86
86
  // Prepare all page hooks so they are prefixed with the `journey.` scope.
87
- pages.forEach((page) => {
88
- /* eslint-disable-next-line no-param-reassign,no-return-assign */
89
- (page?.hooks ?? []).forEach((h) => (h.hook = `journey.${h.hook}`));
90
- });
87
+ for (const page of pages) {
88
+ if (page?.hooks) {
89
+ for (const h of page.hooks) {
90
+ h.hook = `journey.${h.hook}`
91
+ }
92
+ }
93
+ }
91
94
 
92
95
  // Prepare a Nunjucks environment for rendering all templates.
93
96
  // Resolve priority: userland templates > CASA templates > GOVUK templates > Plugin templates
@@ -207,9 +210,9 @@ export default function configure(config = {}) {
207
210
  };
208
211
 
209
212
  // Bootstrap all plugins
210
- plugins
211
- .filter((p) => p.bootstrap)
212
- .forEach((plugin) => plugin?.bootstrap(configOutput));
213
+ for (const plugin of plugins.filter((p) => p.bootstrap)) {
214
+ plugin?.bootstrap(configOutput)
215
+ }
213
216
 
214
217
  // Finished configuration
215
218
  return configOutput;
@@ -18,14 +18,14 @@ const log = logger("lib:end-session");
18
18
  export default function endSession(req, next) {
19
19
  const { language } = req.session;
20
20
 
21
- Object.entries(req.session).forEach(([k]) => {
22
- if (!["cookie"].includes(k)) {
23
- // ESLint disabled as `Object.entries()` returns "own" properties, and
21
+ for (const key of Object.keys(req.session)) {
22
+ if (!["cookie"].includes(key)) {
23
+ // ESLint disabled as `Object.keys()` returns "own" properties, and
24
24
  // all values are being null'd, so not assigned any user-controlled values
25
25
  /* eslint-disable-next-line security/detect-object-injection */
26
- req.session[k] = null;
26
+ req.session[key] = null;
27
27
  }
28
- });
28
+ }
29
29
 
30
30
  req.session.save((saveErr) => {
31
31
  if (saveErr) {
@@ -11,7 +11,8 @@ const { all: deepmergeAll } = merge;
11
11
  const combineMerge = (target, source, options) => {
12
12
  const destination = target.slice();
13
13
 
14
- source.forEach((item, index) => {
14
+ for (let index = 0; index < source.length; index++) {
15
+ const item = source[index];
15
16
  // ESLint disabled as `index` is only an integer
16
17
  /* eslint-disable security/detect-object-injection */
17
18
  if (typeof destination[index] === "undefined") {
@@ -22,7 +23,7 @@ const combineMerge = (target, source, options) => {
22
23
  destination.push(item);
23
24
  }
24
25
  /* eslint-enable security/detect-object-injection */
25
- });
26
+ }
26
27
  return destination;
27
28
  };
28
29
 
@@ -48,8 +49,7 @@ function isPlainObjectOrArray(o) {
48
49
  if (isObject(prot) === false) {
49
50
  return false;
50
51
  }
51
- // eslint-disable-next-line no-prototype-builtins
52
- return prot.hasOwnProperty("isPrototypeOf");
52
+ return Object.hasOwn(prot, "isPrototypeOf");
53
53
  }
54
54
 
55
55
  function mergeObjects(...objects) {
@@ -120,7 +120,7 @@ function formatDateObject(date, config = {}) {
120
120
  function renderAsAttributes(attrsObject) {
121
121
  const attrsList = [];
122
122
  if (typeof attrsObject === "object") {
123
- Object.keys(attrsObject).forEach((key) => {
123
+ for (const key of Object.keys(attrsObject)) {
124
124
  // ESLint disable as `attrsObject` is dev-controlled, `Object.keys()` has
125
125
  // been used (to get "own" properties) and `m` is one of the characters
126
126
  // found by the regex.
@@ -138,7 +138,7 @@ function renderAsAttributes(attrsObject) {
138
138
  );
139
139
  /* eslint-enable security/detect-object-injection */
140
140
  attrsList.push(`${key}="${value}"`);
141
- });
141
+ }
142
142
  }
143
143
  return new nunjucks.runtime.SafeString(attrsList.join(" "));
144
144
  }
@@ -1,5 +1,5 @@
1
- import { readFileSync } from "fs";
2
- import { resolve } from "path";
1
+ import { readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
3
  import { Environment } from "nunjucks";
4
4
  import dirname from "./dirname.cjs";
5
5
  import CasaTemplateLoader from "./CasaTemplateLoader.js";
@@ -98,11 +98,11 @@ export default class DateObject extends ValidatorFactory {
98
98
  formats: ["dd-MMM-yyyy", "dd-MMMM-yyyy"],
99
99
  },
100
100
  ];
101
- formatTests.forEach((test) => {
101
+ for (const test of formatTests) {
102
102
  if (test.flags.every((v) => v === true)) {
103
103
  formats = [...formats, ...test.formats];
104
104
  }
105
- });
105
+ };
106
106
 
107
107
  if (typeof value === "object") {
108
108
  formats.find((format) => {
@@ -145,13 +145,13 @@ export default class DateObject extends ValidatorFactory {
145
145
  // Check presence of each object component (dd, mm, yyyy) in order to log
146
146
  // which specific parts are in error
147
147
  errorMsg.focusSuffix = [];
148
- if (!Object.prototype.hasOwnProperty.call(value, "dd") || !value.dd) {
148
+ if (!Object.hasOwn(value, "dd") || !value.dd) {
149
149
  errorMsg.focusSuffix.push("[dd]");
150
150
  }
151
- if (!Object.prototype.hasOwnProperty.call(value, "mm") || !value.mm) {
151
+ if (!Object.hasOwn(value, "mm") || !value.mm) {
152
152
  errorMsg.focusSuffix.push("[mm]");
153
153
  }
154
- if (!Object.prototype.hasOwnProperty.call(value, "yyyy") || !value.yyyy) {
154
+ if (!Object.hasOwn(value, "yyyy") || !value.yyyy) {
155
155
  errorMsg.focusSuffix.push("[yyyy]");
156
156
  }
157
157
 
@@ -95,13 +95,11 @@ export default class PostalAddressObject extends ValidatorFactory {
95
95
  // Work out required/optional parts based on config
96
96
  const reqF = Object.create(null);
97
97
  const reqC = cfg.requiredFields;
98
- ["address1", "address2", "address3", "address4", "postcode"].forEach(
99
- (k) => {
100
- // ESLint disabled as `k` is a known value from a constant list
101
- /* eslint-disable-next-line security/detect-object-injection */
102
- reqF[k] = reqC.indexOf(k) > -1;
103
- },
104
- );
98
+ reqF.address1 = reqC.indexOf("address1") > -1;
99
+ reqF.address2 = reqC.indexOf("address2") > -1;
100
+ reqF.address3 = reqC.indexOf("address3") > -1;
101
+ reqF.address4 = reqC.indexOf("address4") > -1;
102
+ reqF.postcode = reqC.indexOf("postcode") > -1;
105
103
 
106
104
  let valid = true;
107
105
  const errorMsgs = [];
@@ -129,9 +127,9 @@ export default class PostalAddressObject extends ValidatorFactory {
129
127
  };
130
128
  // ESLint disabled as `k` is a known value from the constant list above
131
129
  /* eslint-disable security/detect-object-injection */
132
- Object.keys(attributes).forEach((k) => {
130
+ for (const k of Object.keys(attributes)) {
133
131
  const attr = attributes[k];
134
- const hasProperty = Object.prototype.hasOwnProperty.call(value, k);
132
+ const hasProperty = Object.hasOwn(value, k);
135
133
  const hasContent = hasProperty && value[k].length > 0;
136
134
 
137
135
  const condMissingOrRegexMismatch =
@@ -147,7 +145,7 @@ export default class PostalAddressObject extends ValidatorFactory {
147
145
  }),
148
146
  );
149
147
  }
150
- });
148
+ }
151
149
  /* eslint-enable security/detect-object-injection */
152
150
  } else {
153
151
  valid = false;