@dwp/govuk-casa 8.15.0 → 9.1.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 (201) hide show
  1. package/README.md +9 -9
  2. package/dist/assets/css/casa.css +2 -1
  3. package/dist/assets/css/casa.css.map +1 -0
  4. package/dist/casa.d.ts +122 -99
  5. package/dist/casa.js +120 -88
  6. package/dist/casa.js.map +1 -1
  7. package/dist/lib/CasaTemplateLoader.d.ts +4 -4
  8. package/dist/lib/CasaTemplateLoader.js +16 -16
  9. package/dist/lib/CasaTemplateLoader.js.map +1 -1
  10. package/dist/lib/JourneyContext.d.ts +38 -40
  11. package/dist/lib/JourneyContext.js +89 -75
  12. package/dist/lib/JourneyContext.js.map +1 -1
  13. package/dist/lib/MutableRouter.d.ts +40 -41
  14. package/dist/lib/MutableRouter.js +64 -71
  15. package/dist/lib/MutableRouter.js.map +1 -1
  16. package/dist/lib/Plan.d.ts +29 -26
  17. package/dist/lib/Plan.js +85 -71
  18. package/dist/lib/Plan.js.map +1 -1
  19. package/dist/lib/ValidationError.d.ts +16 -15
  20. package/dist/lib/ValidationError.js +21 -20
  21. package/dist/lib/ValidationError.js.map +1 -1
  22. package/dist/lib/ValidatorFactory.d.ts +15 -13
  23. package/dist/lib/ValidatorFactory.js +14 -12
  24. package/dist/lib/ValidatorFactory.js.map +1 -1
  25. package/dist/lib/configuration-ingestor.d.ts +37 -40
  26. package/dist/lib/configuration-ingestor.js +93 -93
  27. package/dist/lib/configuration-ingestor.js.map +1 -1
  28. package/dist/lib/configure.d.ts +6 -6
  29. package/dist/lib/configure.js +14 -12
  30. package/dist/lib/configure.js.map +1 -1
  31. package/dist/lib/constants.d.ts +1 -3
  32. package/dist/lib/constants.js +9 -11
  33. package/dist/lib/constants.js.map +1 -1
  34. package/dist/lib/context-id-generators.d.ts +3 -5
  35. package/dist/lib/context-id-generators.js +7 -6
  36. package/dist/lib/context-id-generators.js.map +1 -1
  37. package/dist/lib/end-session.d.ts +4 -4
  38. package/dist/lib/end-session.js +5 -5
  39. package/dist/lib/field.d.ts +24 -29
  40. package/dist/lib/field.js +41 -70
  41. package/dist/lib/field.js.map +1 -1
  42. package/dist/lib/index.d.ts +13 -13
  43. package/dist/lib/logger.d.ts +7 -6
  44. package/dist/lib/logger.js +7 -7
  45. package/dist/lib/logger.js.map +1 -1
  46. package/dist/lib/mount.d.ts +5 -5
  47. package/dist/lib/mount.js +12 -17
  48. package/dist/lib/mount.js.map +1 -1
  49. package/dist/lib/nunjucks-filters.d.ts +10 -12
  50. package/dist/lib/nunjucks-filters.js +35 -35
  51. package/dist/lib/nunjucks-filters.js.map +1 -1
  52. package/dist/lib/nunjucks.d.ts +7 -5
  53. package/dist/lib/nunjucks.js +10 -8
  54. package/dist/lib/nunjucks.js.map +1 -1
  55. package/dist/lib/utils.d.ts +19 -19
  56. package/dist/lib/utils.js +62 -55
  57. package/dist/lib/utils.js.map +1 -1
  58. package/dist/lib/validators/dateObject.d.ts +29 -22
  59. package/dist/lib/validators/dateObject.js +58 -49
  60. package/dist/lib/validators/dateObject.js.map +1 -1
  61. package/dist/lib/validators/email.d.ts +4 -4
  62. package/dist/lib/validators/email.js +4 -4
  63. package/dist/lib/validators/inArray.d.ts +4 -4
  64. package/dist/lib/validators/inArray.js +7 -8
  65. package/dist/lib/validators/inArray.js.map +1 -1
  66. package/dist/lib/validators/index.d.ts +10 -10
  67. package/dist/lib/validators/index.js +1 -3
  68. package/dist/lib/validators/index.js.map +1 -1
  69. package/dist/lib/validators/nino.d.ts +9 -8
  70. package/dist/lib/validators/nino.js +14 -10
  71. package/dist/lib/validators/nino.js.map +1 -1
  72. package/dist/lib/validators/postalAddressObject.d.ts +37 -24
  73. package/dist/lib/validators/postalAddressObject.js +65 -46
  74. package/dist/lib/validators/postalAddressObject.js.map +1 -1
  75. package/dist/lib/validators/range.d.ts +12 -8
  76. package/dist/lib/validators/range.js +11 -9
  77. package/dist/lib/validators/range.js.map +1 -1
  78. package/dist/lib/validators/regex.d.ts +4 -4
  79. package/dist/lib/validators/regex.js +5 -5
  80. package/dist/lib/validators/required.d.ts +6 -6
  81. package/dist/lib/validators/required.js +9 -11
  82. package/dist/lib/validators/required.js.map +1 -1
  83. package/dist/lib/validators/strlen.d.ts +12 -8
  84. package/dist/lib/validators/strlen.js +13 -11
  85. package/dist/lib/validators/strlen.js.map +1 -1
  86. package/dist/lib/validators/wordCount.d.ts +12 -8
  87. package/dist/lib/validators/wordCount.js +15 -11
  88. package/dist/lib/validators/wordCount.js.map +1 -1
  89. package/dist/lib/waypoint-url.d.ts +16 -13
  90. package/dist/lib/waypoint-url.js +39 -36
  91. package/dist/lib/waypoint-url.js.map +1 -1
  92. package/dist/middleware/body-parser.d.ts +1 -1
  93. package/dist/middleware/body-parser.js +6 -6
  94. package/dist/middleware/body-parser.js.map +1 -1
  95. package/dist/middleware/data.d.ts +1 -1
  96. package/dist/middleware/data.js +8 -7
  97. package/dist/middleware/data.js.map +1 -1
  98. package/dist/middleware/gather-fields.d.ts +2 -2
  99. package/dist/middleware/gather-fields.js +6 -4
  100. package/dist/middleware/gather-fields.js.map +1 -1
  101. package/dist/middleware/i18n.js +13 -15
  102. package/dist/middleware/i18n.js.map +1 -1
  103. package/dist/middleware/post.js +30 -18
  104. package/dist/middleware/post.js.map +1 -1
  105. package/dist/middleware/pre.d.ts +2 -2
  106. package/dist/middleware/pre.js +46 -26
  107. package/dist/middleware/pre.js.map +1 -1
  108. package/dist/middleware/progress-journey.d.ts +1 -1
  109. package/dist/middleware/progress-journey.js +5 -5
  110. package/dist/middleware/progress-journey.js.map +1 -1
  111. package/dist/middleware/sanitise-fields.d.ts +1 -1
  112. package/dist/middleware/sanitise-fields.js +13 -11
  113. package/dist/middleware/sanitise-fields.js.map +1 -1
  114. package/dist/middleware/serve-first-waypoint.d.ts +3 -3
  115. package/dist/middleware/serve-first-waypoint.js +8 -6
  116. package/dist/middleware/serve-first-waypoint.js.map +1 -1
  117. package/dist/middleware/session.js +14 -11
  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 +16 -14
  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 +1 -1
  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 +3 -3
  132. package/dist/routes/ancillary.js +4 -4
  133. package/dist/routes/ancillary.js.map +1 -1
  134. package/dist/routes/journey.d.ts +2 -2
  135. package/dist/routes/journey.js +91 -39
  136. package/dist/routes/journey.js.map +1 -1
  137. package/dist/routes/static.d.ts +7 -5
  138. package/dist/routes/static.js +20 -20
  139. package/dist/routes/static.js.map +1 -1
  140. package/package.json +17 -16
  141. package/src/casa.js +134 -102
  142. package/src/lib/CasaTemplateLoader.js +24 -19
  143. package/src/lib/JourneyContext.js +147 -107
  144. package/src/lib/MutableRouter.js +72 -74
  145. package/src/lib/Plan.js +145 -97
  146. package/src/lib/ValidationError.js +25 -21
  147. package/src/lib/ValidatorFactory.js +17 -13
  148. package/src/lib/configuration-ingestor.js +147 -110
  149. package/src/lib/configure.js +34 -32
  150. package/src/lib/constants.js +9 -11
  151. package/src/lib/context-id-generators.js +40 -43
  152. package/src/lib/end-session.js +6 -6
  153. package/src/lib/field.js +74 -78
  154. package/src/lib/index.js +12 -12
  155. package/src/lib/logger.js +9 -9
  156. package/src/lib/mount.js +70 -80
  157. package/src/lib/nunjucks-filters.js +56 -59
  158. package/src/lib/nunjucks.js +23 -18
  159. package/src/lib/utils.js +78 -57
  160. package/src/lib/validators/dateObject.js +71 -60
  161. package/src/lib/validators/email.js +8 -8
  162. package/src/lib/validators/inArray.js +10 -11
  163. package/src/lib/validators/index.js +12 -14
  164. package/src/lib/validators/nino.js +29 -15
  165. package/src/lib/validators/postalAddressObject.js +87 -63
  166. package/src/lib/validators/range.js +14 -12
  167. package/src/lib/validators/regex.js +8 -8
  168. package/src/lib/validators/required.js +16 -16
  169. package/src/lib/validators/strlen.js +16 -14
  170. package/src/lib/validators/wordCount.js +22 -14
  171. package/src/lib/waypoint-url.js +64 -46
  172. package/src/middleware/body-parser.js +10 -10
  173. package/src/middleware/csrf.js +1 -1
  174. package/src/middleware/data.js +28 -24
  175. package/src/middleware/gather-fields.js +10 -9
  176. package/src/middleware/i18n.js +35 -37
  177. package/src/middleware/post.js +41 -21
  178. package/src/middleware/pre.js +62 -40
  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 +14 -12
  182. package/src/middleware/session.js +74 -61
  183. package/src/middleware/skip-waypoint.js +7 -9
  184. package/src/middleware/steer-journey.js +40 -28
  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 +5 -7
  188. package/src/routes/journey.js +159 -85
  189. package/src/routes/static.js +62 -30
  190. package/views/casa/components/character-count/README.md +2 -2
  191. package/views/casa/components/checkboxes/README.md +6 -6
  192. package/views/casa/components/date-input/README.md +7 -7
  193. package/views/casa/components/input/README.md +2 -2
  194. package/views/casa/components/journey-form/README.md +33 -14
  195. package/views/casa/components/postal-address-object/README.md +4 -4
  196. package/views/casa/components/radios/README.md +6 -6
  197. package/views/casa/components/select/README.md +6 -6
  198. package/views/casa/components/textarea/README.md +2 -2
  199. package/views/casa/partials/scripts.njk +5 -3
  200. package/views/casa/partials/styles.njk +1 -4
  201. package/dist/assets/css/casa-ie8.css +0 -1
@@ -1,42 +1,42 @@
1
- import { MemoryStore } from 'express-session';
2
- import { resolve } from 'path';
3
- import { createRequire } from 'module';
4
- import cookieParserFactory from 'cookie-parser';
5
- import dirname from './dirname.cjs';
1
+ import { MemoryStore } from "express-session";
2
+ import { resolve } from "path";
3
+ import { createRequire } from "module";
4
+ import cookieParserFactory from "cookie-parser";
5
+ import dirname from "./dirname.cjs";
6
6
 
7
- import configurationIngestor from './configuration-ingestor.js';
8
- import nunjucks from './nunjucks.js';
9
- import mountFactory from './mount.js';
7
+ import configurationIngestor from "./configuration-ingestor.js";
8
+ import nunjucks from "./nunjucks.js";
9
+ import mountFactory from "./mount.js";
10
10
 
11
- import staticRoutes from '../routes/static.js';
12
- import ancillaryRoutes from '../routes/ancillary.js';
13
- import journeyRoutes from '../routes/journey.js';
11
+ import staticRoutes from "../routes/static.js";
12
+ import ancillaryRoutes from "../routes/ancillary.js";
13
+ import journeyRoutes from "../routes/journey.js";
14
14
 
15
- import preMiddlewareFactory from '../middleware/pre.js';
16
- import postMiddlewareFactory from '../middleware/post.js';
15
+ import preMiddlewareFactory from "../middleware/pre.js";
16
+ import postMiddlewareFactory from "../middleware/post.js";
17
17
 
18
- import sessionMiddlewareFactory from '../middleware/session.js';
19
- import i18nMiddlewareFactory from '../middleware/i18n.js';
20
- import dataMiddlewareFactory from '../middleware/data.js';
18
+ import sessionMiddlewareFactory from "../middleware/session.js";
19
+ import i18nMiddlewareFactory from "../middleware/i18n.js";
20
+ import dataMiddlewareFactory from "../middleware/data.js";
21
21
 
22
- import bodyParserMiddlewareFactory from '../middleware/body-parser.js';
23
- import csrfMiddlewareFactory from '../middleware/csrf.js';
22
+ import bodyParserMiddlewareFactory from "../middleware/body-parser.js";
23
+ import csrfMiddlewareFactory from "../middleware/csrf.js";
24
24
 
25
- import { CONFIG_ERROR_VISIBILITY_ONSUBMIT } from './constants.js';
25
+ import { CONFIG_ERROR_VISIBILITY_ONSUBMIT } from "./constants.js";
26
26
 
27
27
  /**
28
+ * @typedef {import("../casa").ConfigurationOptions} ConfigurationOptions
28
29
  * @access private
29
- * @typedef {import('../casa').ConfigurationOptions} ConfigurationOptions
30
30
  */
31
31
 
32
32
  /**
33
+ * @typedef {import("../casa").ConfigureResult} ConfigureResult
33
34
  * @access private
34
- * @typedef {import('../casa').ConfigureResult} ConfigureResult
35
35
  */
36
36
 
37
37
  /**
38
+ * @typedef {import("../casa").Mounter} Mounter
38
39
  * @access private
39
- * @typedef {import('../casa').Mounter} Mounter
40
40
  */
41
41
 
42
42
  /**
@@ -60,12 +60,12 @@ export default function configure(config = {}) {
60
60
  errorVisibility = CONFIG_ERROR_VISIBILITY_ONSUBMIT,
61
61
  views = [],
62
62
  session = {
63
- secret: 'secret',
64
- name: 'casasession',
63
+ secret: "secret",
64
+ name: "casasession",
65
65
  secure: false,
66
66
  ttl: 3600,
67
67
  cookieSameSite: true,
68
- cookiePath: '/',
68
+ cookiePath: "/",
69
69
  store: undefined,
70
70
  },
71
71
  pages = [],
@@ -75,7 +75,7 @@ export default function configure(config = {}) {
75
75
  events = [],
76
76
  i18n = {
77
77
  dirs: [],
78
- locales: ['en', 'cy'],
78
+ locales: ["en", "cy"],
79
79
  },
80
80
  helmetConfigurator = undefined,
81
81
  formMaxParams,
@@ -86,7 +86,7 @@ export default function configure(config = {}) {
86
86
  // Prepare all page hooks so they are prefixed with the `journey.` scope.
87
87
  pages.forEach((page) => {
88
88
  /* eslint-disable-next-line no-param-reassign,no-return-assign */
89
- (page?.hooks ?? []).forEach((h) => h.hook = `journey.${h.hook}`);
89
+ (page?.hooks ?? []).forEach((h) => (h.hook = `journey.${h.hook}`));
90
90
  });
91
91
 
92
92
  // Prepare a Nunjucks environment for rendering all templates.
@@ -94,8 +94,8 @@ export default function configure(config = {}) {
94
94
  const nunjucksEnv = nunjucks({
95
95
  views: [
96
96
  ...views,
97
- resolve(dirname, '../../views'),
98
- resolve(createRequire(dirname).resolve('govuk-frontend'), '../../'),
97
+ resolve(dirname, "../../views"),
98
+ resolve(createRequire(dirname).resolve("govuk-frontend"), "../../"),
99
99
  ],
100
100
  });
101
101
 
@@ -120,7 +120,7 @@ export default function configure(config = {}) {
120
120
  const i18nMiddleware = i18nMiddlewareFactory({
121
121
  directories: [
122
122
  // Order is important; latter directories take precedence
123
- resolve(dirname, '../../locales/'),
123
+ resolve(dirname, "../../locales/"),
124
124
  ...i18n.dirs,
125
125
  ],
126
126
  languages: i18n.locales,
@@ -148,7 +148,7 @@ export default function configure(config = {}) {
148
148
  });
149
149
 
150
150
  // Setup waypoint router, which includes routes for every defined waypoint
151
- const globalErrorVisibility = errorVisibility
151
+ const globalErrorVisibility = errorVisibility;
152
152
  const journeyRouter = journeyRoutes({
153
153
  globalHooks: hooks,
154
154
  pages,
@@ -207,7 +207,9 @@ export default function configure(config = {}) {
207
207
  };
208
208
 
209
209
  // Bootstrap all plugins
210
- plugins.filter((p) => p.bootstrap).forEach((plugin) => plugin?.bootstrap(configOutput));
210
+ plugins
211
+ .filter((p) => p.bootstrap)
212
+ .forEach((plugin) => plugin?.bootstrap(configOutput));
211
213
 
212
214
  // Finished configuration
213
215
  return configOutput;
@@ -1,11 +1,9 @@
1
- /**
2
- * General-purpose references to the different request lifecycle phases.
3
- */
4
- export const REQUEST_PHASE_STEER = Symbol('steer');
5
- export const REQUEST_PHASE_SANITISE = Symbol('sanitise');
6
- export const REQUEST_PHASE_GATHER = Symbol('gather');
7
- export const REQUEST_PHASE_VALIDATE = Symbol('validate');
8
- export const REQUEST_PHASE_REDIRECT = Symbol('redirect');
9
- export const REQUEST_PHASE_RENDER = Symbol('render');
10
- export const CONFIG_ERROR_VISIBILITY_ONSUBMIT = Symbol('onsubmit');
11
- export const CONFIG_ERROR_VISIBILITY_ALWAYS = Symbol('always');
1
+ /** General-purpose references to the different request lifecycle phases. */
2
+ export const REQUEST_PHASE_STEER = Symbol("steer");
3
+ export const REQUEST_PHASE_SANITISE = Symbol("sanitise");
4
+ export const REQUEST_PHASE_GATHER = Symbol("gather");
5
+ export const REQUEST_PHASE_VALIDATE = Symbol("validate");
6
+ export const REQUEST_PHASE_REDIRECT = Symbol("redirect");
7
+ export const REQUEST_PHASE_RENDER = Symbol("render");
8
+ export const CONFIG_ERROR_VISIBILITY_ONSUBMIT = Symbol("onsubmit");
9
+ export const CONFIG_ERROR_VISIBILITY_ALWAYS = Symbol("always");
@@ -1,9 +1,7 @@
1
1
  /* eslint-disable import/no-cycle */
2
- import { randomUUID } from 'node:crypto';
2
+ import { randomUUID } from "node:crypto";
3
3
 
4
- /**
5
- * @typedef {import('../casa.js').ContextIdGenerator} ContextIdGenerator
6
- */
4
+ /** @typedef {import("../casa.js").ContextIdGenerator} ContextIdGenerator */
7
5
 
8
6
  /**
9
7
  * Creates an instance of a UUID generator.
@@ -21,51 +19,50 @@ const uuid = () => () => randomUUID();
21
19
  *
22
20
  * @returns {ContextIdGenerator} Generator function
23
21
  */
24
- const sequentialInteger = () => ({ reservedIds }) => {
25
- const contextIds = Array.from(reservedIds).sort();
22
+ const sequentialInteger =
23
+ () =>
24
+ ({ reservedIds }) => {
25
+ const contextIds = Array.from(reservedIds).sort();
26
26
 
27
- if (!contextIds.length) {
28
- return '1';
29
- }
27
+ if (!contextIds.length) {
28
+ return "1";
29
+ }
30
30
 
31
- // Find the first numeric ID that we can increment
32
- let lastInSequence;
33
- do {
34
- lastInSequence = Number.parseInt(contextIds.pop(), 10);
35
- } while (contextIds.length && Number.isNaN(lastInSequence));
31
+ // Find the first numeric ID that we can increment
32
+ let lastInSequence;
33
+ do {
34
+ lastInSequence = Number.parseInt(contextIds.pop(), 10);
35
+ } while (contextIds.length && Number.isNaN(lastInSequence));
36
36
 
37
- return String(!Number.isNaN(lastInSequence) ? lastInSequence + 1 : 1);
38
- };
37
+ return String(!Number.isNaN(lastInSequence) ? lastInSequence + 1 : 1);
38
+ };
39
39
 
40
- const shortGuid = ({
41
- length = 5,
42
- prefix = '',
43
- pool = 'abcdefhkmnprtwxy346789',
44
- } = {}) => ({ reservedIds }) => {
45
- // Ambiguous characters excluded
46
- const poolSize = pool.length;
40
+ const shortGuid =
41
+ ({ length = 5, prefix = "", pool = "abcdefhkmnprtwxy346789" } = {}) =>
42
+ ({ reservedIds }) => {
43
+ // Ambiguous characters excluded
44
+ const poolSize = pool.length;
47
45
 
48
- const maxAttempts = 10;
49
- let attempts = maxAttempts;
50
- let id;
46
+ const maxAttempts = 10;
47
+ let attempts = maxAttempts;
48
+ let id;
51
49
 
52
- do {
53
- id = Array(length).fill(0).map(() => pool.charAt(Math.floor(Math.random() * poolSize))).join('');
54
- attempts--;
55
- } while (attempts > 0 && reservedIds.includes(id));
50
+ do {
51
+ id = Array(length)
52
+ .fill(0)
53
+ .map(() => pool.charAt(Math.floor(Math.random() * poolSize)))
54
+ .join("");
55
+ attempts--;
56
+ } while (attempts > 0 && reservedIds.includes(id));
56
57
 
57
- if (attempts === 0) {
58
- throw new Error(`Failed to generate GUID after ${maxAttempts} iterations`);
59
- }
58
+ if (attempts === 0) {
59
+ throw new Error(
60
+ `Failed to generate GUID after ${maxAttempts} iterations`,
61
+ );
62
+ }
60
63
 
61
- return `${prefix}${id}`;
62
- }
64
+ return `${prefix}${id}`;
65
+ };
63
66
 
64
- /**
65
- * @namespace ContextIdGenerators
66
- */
67
- export {
68
- uuid,
69
- sequentialInteger,
70
- shortGuid,
71
- };
67
+ /** @namespace ContextIdGenerators */
68
+ export { uuid, sequentialInteger, shortGuid };
@@ -1,17 +1,17 @@
1
- import logger from './logger.js';
1
+ import logger from "./logger.js";
2
2
 
3
- const log = logger('lib:end-session');
3
+ const log = logger("lib:end-session");
4
4
 
5
5
  /**
6
6
  * A convenience for ending the current session, but retaining some data in it,
7
- * like the current language. It persists an empty session before regenerating
8
- * a new ID.
7
+ * like the current language. It persists an empty session before regenerating a
8
+ * new ID.
9
9
  *
10
10
  * Note: this will not remove the session from server-side storage, which will
11
11
  * instead be left up to the storage mechanism to clean up.
12
12
  *
13
13
  * @memberof module:@dwp/govuk-casa
14
- * @param {import('express').Request} req HTTP request
14
+ * @param {import("express").Request} req HTTP request
15
15
  * @param {Function} next Chain
16
16
  * @returns {void}
17
17
  */
@@ -19,7 +19,7 @@ export default function endSession(req, next) {
19
19
  const { language } = req.session;
20
20
 
21
21
  Object.entries(req.session).forEach(([k]) => {
22
- if (!['cookie'].includes(k)) {
22
+ if (!["cookie"].includes(k)) {
23
23
  // ESLint disabled as `Object.entries()` 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 */
package/src/lib/field.js CHANGED
@@ -1,38 +1,36 @@
1
- import lodash from 'lodash';
2
- import { isEmpty } from './utils.js';
3
- import logger from './logger.js';
1
+ import lodash from "lodash";
2
+ import { isEmpty } from "./utils.js";
4
3
 
5
- const log = logger('lib:field');
6
4
  const { isFunction } = lodash;
7
5
 
8
6
  /**
7
+ * @typedef {import("./index").JourneyContext} JourneyContext
9
8
  * @access private
10
- * @typedef {import('./index').JourneyContext} JourneyContext
11
9
  */
12
10
 
13
11
  /**
12
+ * @typedef {import("../casa").Validator} Validator
14
13
  * @access private
15
- * @typedef {import('../casa').Validator} Validator
16
14
  */
17
15
 
18
16
  /**
17
+ * @typedef {import("../casa").ValidateContext} ValidateContext
19
18
  * @access private
20
- * @typedef {import('../casa').ValidateContext} ValidateContext
21
19
  */
22
20
 
23
21
  /**
22
+ * @typedef {import("../casa").ValidatorConditionFunction} ValidatorConditionFunction
24
23
  * @access private
25
- * @typedef {import('../casa').ValidatorConditionFunction} ValidatorConditionFunction
26
24
  */
27
25
 
28
26
  /**
27
+ * @typedef {import("../casa").FieldProcessorFunction} FieldProcessorFunction
29
28
  * @access private
30
- * @typedef {import('../casa').FieldProcessorFunction} FieldProcessorFunction
31
29
  */
32
30
 
33
31
  /**
32
+ * @typedef {import("./index").ValidationError} ValidationError
34
33
  * @access private
35
- * @typedef {import('./index').ValidationError} ValidationError
36
34
  */
37
35
 
38
36
  // Quick check to see if the field name corresponds to a non-primitive complex
@@ -48,29 +46,19 @@ const reInvalidName = /[^a-z0-9_.\-[\]]/i;
48
46
  * @class
49
47
  */
50
48
  export class PageField {
51
- /**
52
- * @type {string}
53
- */
49
+ /** @type {string} */
54
50
  #name;
55
51
 
56
- /**
57
- * @type {FieldProcessorFunction[]}
58
- */
52
+ /** @type {FieldProcessorFunction[]} */
59
53
  #processors;
60
54
 
61
- /**
62
- * @type {Validator[]}
63
- */
55
+ /** @type {Validator[]} */
64
56
  #validators;
65
57
 
66
- /**
67
- * @type {ValidatorConditionFunction[]}
68
- */
58
+ /** @type {ValidatorConditionFunction[]} */
69
59
  #conditions;
70
60
 
71
- /**
72
- * @type {object}
73
- */
61
+ /** @type {object} */
74
62
  #meta;
75
63
 
76
64
  /**
@@ -78,12 +66,19 @@ export class PageField {
78
66
  *
79
67
  * @param {string} name Field name
80
68
  * @param {object} [opts] Options
81
- * @param {boolean} [opts.optional=false] Whether this field is optional
82
- * @param {boolean} [opts.persist=true] Whether this field will persist in `req.body`
69
+ * @param {boolean} [opts.optional=false] Whether this field is optional.
70
+ * Default is `false`
71
+ * @param {boolean} [opts.persist=true] Whether this field will persist in
72
+ * `req.body`. Default is `true`
83
73
  */
84
- constructor(name, { optional = false, persist = true } = Object.create(null)) {
74
+ constructor(
75
+ name,
76
+ { optional = false, persist = true } = Object.create(null),
77
+ ) {
85
78
  if (!name) {
86
- throw new SyntaxError('A name for this field is required, i.e. "field(\'myField\')".');
79
+ throw new SyntaxError(
80
+ "A name for this field is required, i.e. \"field('myField')\".",
81
+ );
87
82
  }
88
83
 
89
84
  this.#name = undefined;
@@ -139,7 +134,9 @@ export class PageField {
139
134
  */
140
135
  getValue(obj = Object.create(null)) {
141
136
  if (this.#meta.complex) {
142
- return obj[this.#meta.complexFieldName]?.[this.#meta.complexFieldProperty];
137
+ return obj[this.#meta.complexFieldName]?.[
138
+ this.#meta.complexFieldProperty
139
+ ];
143
140
  }
144
141
  return obj[this.#name];
145
142
  }
@@ -188,7 +185,9 @@ export class PageField {
188
185
  */
189
186
  rename(name) {
190
187
  if (reInvalidName.test(String(name))) {
191
- throw new SyntaxError(`Field '${String(name)}' name contains invalid characters.`);
188
+ throw new SyntaxError(
189
+ `Field '${String(name)}' name contains invalid characters.`,
190
+ );
192
191
  }
193
192
 
194
193
  // Complex names are only supported to one level deep. For example,
@@ -196,7 +195,9 @@ export class PageField {
196
195
  // early to aid developer.
197
196
  const isComplex = reComplexType.test(name);
198
197
  if (isComplex && name.match(/\[/g).length > 1) {
199
- throw new SyntaxError('Complex field names are only supported to 1 property depth. E.g. a[b] is ok, a[b][c] is not');
198
+ throw new SyntaxError(
199
+ "Complex field names are only supported to 1 property depth. E.g. a[b] is ok, a[b][c] is not",
200
+ );
200
201
  }
201
202
 
202
203
  this.#name = String(name);
@@ -221,21 +222,19 @@ export class PageField {
221
222
  }
222
223
 
223
224
  /**
224
- * Add/get value validators
225
- * Some validators will include a `sanitise()` method which will be run at the
226
- * same time as other "processors".
225
+ * Add value validators Some validators will include a `sanitise()` method
226
+ * which will be run at the same time as other "processors".
227
227
  *
228
228
  * @param {Validator[]} items Validation functions
229
- * @returns {PageField} Chain - Deprecated: this currently gets all validators if
230
- * empty or missing, in v9 this functionality will removed in favour of the
231
- * function getValidators().
229
+ * @returns {PageField} Chain
232
230
  */
233
231
  validators(items = []) {
234
232
  if (!items.length) {
235
- log.warn('Calling validators() to get all validators is deprecated, please use getValidators()');
236
- return this.getValidators();
233
+ throw new Error(
234
+ "Calling validators() to get all validators is no longer supported, please use getValidators()",
235
+ );
237
236
  }
238
- this.#validators = [...this.#validators, ...(items.flat())];
237
+ this.#validators = [...this.#validators, ...items.flat()];
239
238
  return this;
240
239
  }
241
240
 
@@ -249,21 +248,20 @@ export class PageField {
249
248
  }
250
249
 
251
250
  /**
252
- * Add/get value pre-processors
253
- * This is most often used to sanitise values to a particular data type.
251
+ * Add value pre-processors This is most often used to sanitise values to a
252
+ * particular data type.
254
253
  *
255
254
  * @param {FieldProcessorFunction[]} items Processor functions
256
- * @returns {PageField} Chain - Deprecated: this currently gets all processors if
257
- * empty or missing, in v9 this functionality will removed in favour of the
258
- * function getProcessors().
255
+ * @returns {PageField} Chain
259
256
  */
260
257
  processors(items = []) {
261
258
  if (!items.length) {
262
- log.warn('Calling processors() to get all processors is deprecated, please use getProcessors()');
263
- return this.getProcessors();
259
+ throw new Error(
260
+ "Calling processors() to get all processors is no longer supported, please use getProcessors()",
261
+ );
264
262
  }
265
263
 
266
- this.#processors = [...this.#processors, ...(items.flat())];
264
+ this.#processors = [...this.#processors, ...items.flat()];
267
265
  return this;
268
266
  }
269
267
 
@@ -277,21 +275,19 @@ export class PageField {
277
275
  }
278
276
 
279
277
  /**
280
- * Add/get conditions
281
- * All conditions must be met in order for this field to be considered
282
- * "actionable".
278
+ * Add conditions All conditions must be met in order for this field to be
279
+ * considered "actionable".
283
280
  *
284
281
  * @param {ValidatorConditionFunction[]} items Condition functions
285
- * @returns {PageField} Chain - Deprecated: this currently gets all conditions if
286
- * empty or missing, in v9 this functionality will removed in favour of the
287
- * function getConditions().
282
+ * @returns {PageField} Chain
288
283
  */
289
284
  conditions(items = []) {
290
285
  if (!items.length) {
291
- log.warn('Calling conditions() to get all conditions is deprecated, please use getConditions()');
292
- return this.getConditions();
286
+ throw new Error(
287
+ "Calling conditions() to get all conditions is no longer supported, please use getConditions()",
288
+ );
293
289
  }
294
- this.#conditions = [...this.#conditions, ...(items.flat())];
290
+ this.#conditions = [...this.#conditions, ...items.flat()];
295
291
  return this;
296
292
  }
297
293
 
@@ -300,22 +296,17 @@ export class PageField {
300
296
  /**
301
297
  * Run all validators and return array of errors, if applicable.
302
298
  *
303
- * @param {any} value Value to validate
304
299
  * @param {ValidateContext} context Contextual validation information
305
300
  * @returns {ValidationError[]} Errors, or an empty array if all valid
306
301
  * @throws {TypeError} If validator does not return an array
307
302
  */
308
- runValidators(value, context = Object.create(null)) {
303
+ runValidators(context = Object.create(null)) {
309
304
  // Skip validation if the field is empty and optional
310
- if (this.#meta.optional && isEmpty(value)) {
305
+ if (this.#meta.optional && isEmpty(context?.fieldValue)) {
311
306
  return [];
312
307
  }
313
308
 
314
309
  // Skip validation if conditions are not met
315
- // We duplicate value in context.fieldValue for historical reasons
316
- // @todo explain these historical reasons! And deprecate the need for
317
- // `value` altogether
318
- context.fieldValue = context.fieldValue ?? value;
319
310
  if (!this.testConditions(context)) {
320
311
  return [];
321
312
  }
@@ -325,22 +316,26 @@ export class PageField {
325
316
  // ESLint disabled as `i` is an integer
326
317
  /* eslint-disable security/detect-object-injection */
327
318
  // TODO: Replace `value` with `context.fieldValue` here
328
- let fieldErrors = this.#validators[i].validate(value, context)
319
+ let fieldErrors = this.#validators[i].validate(
320
+ context.fieldValue,
321
+ context,
322
+ );
329
323
  if (!Array.isArray(fieldErrors)) {
330
324
  // Friendly message for developer
331
- throw new TypeError(`The validator at index ${i} (name: ${this.#validators[i].name || 'unknown'}) for field '${this.#name}' did not return an array`);
325
+ throw new TypeError(
326
+ `The validator at index ${i} (name: ${this.#validators[i].name || "unknown"}) for field '${this.#name}' did not return an array`,
327
+ );
332
328
  }
333
329
 
334
- fieldErrors = fieldErrors.map((e) => e.withContext({
335
- ...context,
336
- validator: this.#validators[i].name,
337
- }));
330
+ fieldErrors = fieldErrors.map((e) =>
331
+ e.withContext({
332
+ ...context,
333
+ validator: this.#validators[i].name,
334
+ }),
335
+ );
338
336
  /* eslint-enable security/detect-object-injection */
339
337
 
340
- errors = [
341
- ...errors,
342
- ...(fieldErrors ?? []),
343
- ];
338
+ errors = [...errors, ...(fieldErrors ?? [])];
344
339
  }
345
340
 
346
341
  return errors;
@@ -385,7 +380,6 @@ export class PageField {
385
380
  fieldName: this.#name,
386
381
  fieldValue,
387
382
  waypoint,
388
- waypointId: waypoint, // [DEPRECATED] for backwards compatibility with v7
389
383
  journeyContext,
390
384
  };
391
385
 
@@ -447,8 +441,10 @@ export class PageField {
447
441
  * @memberof module:@dwp/govuk-casa
448
442
  * @param {string} name Field name
449
443
  * @param {object} [opts] Options
450
- * @param {boolean} [opts.optional=false] Whether this field is optional
451
- * @param {boolean} [opts.persist=true] Whether this field will persist in `req.body`
444
+ * @param {boolean} [opts.optional=false] Whether this field is optional.
445
+ * Default is `false`
446
+ * @param {boolean} [opts.persist=true] Whether this field will persist in
447
+ * `req.body`. Default is `true`
452
448
  * @returns {PageField} A PageField
453
449
  */
454
450
  export default function field(name, opts) {
package/src/lib/index.js CHANGED
@@ -3,18 +3,18 @@
3
3
  * imported anywhere in code, other than JSDoc references.
4
4
  */
5
5
 
6
- import CasaTemplateLoader from './CasaTemplateLoader.js';
7
- import configure from './configure.js';
8
- import configurationIngestor from './configuration-ingestor.js';
9
- import endSession from './end-session.js';
10
- import field, { PageField } from './field.js';
11
- import JourneyContext from './JourneyContext.js';
12
- import MutableRouter from './MutableRouter.js';
13
- import Plan from './Plan.js';
14
- import ValidationError from './ValidationError.js';
15
- import ValidatorFactory from './ValidatorFactory.js';
16
- import waypointUrl from './waypoint-url.js';
17
- import * as utils from './utils.js';
6
+ import CasaTemplateLoader from "./CasaTemplateLoader.js";
7
+ import configure from "./configure.js";
8
+ import configurationIngestor from "./configuration-ingestor.js";
9
+ import endSession from "./end-session.js";
10
+ import field, { PageField } from "./field.js";
11
+ import JourneyContext from "./JourneyContext.js";
12
+ import MutableRouter from "./MutableRouter.js";
13
+ import Plan from "./Plan.js";
14
+ import ValidationError from "./ValidationError.js";
15
+ import ValidatorFactory from "./ValidatorFactory.js";
16
+ import waypointUrl from "./waypoint-url.js";
17
+ import * as utils from "./utils.js";
18
18
 
19
19
  export {
20
20
  CasaTemplateLoader,
package/src/lib/logger.js CHANGED
@@ -1,16 +1,16 @@
1
- import debug from 'debug';
1
+ import debug from "debug";
2
2
 
3
- const casaDebugger = debug('casa');
3
+ const casaDebugger = debug("casa");
4
4
 
5
5
  export default (namespace) => {
6
6
  const logger = casaDebugger.extend(namespace);
7
7
 
8
8
  return {
9
- trace: logger.extend('trace'),
10
- debug: logger.extend('debug'),
11
- info: logger.extend('info'),
12
- warn: logger.extend('warn'),
13
- error: logger.extend('error'),
14
- fatal: logger.extend('fatal'),
9
+ trace: logger.extend("trace"),
10
+ debug: logger.extend("debug"),
11
+ info: logger.extend("info"),
12
+ warn: logger.extend("warn"),
13
+ error: logger.extend("error"),
14
+ fatal: logger.extend("fatal"),
15
15
  };
16
- }
16
+ };