@dwp/govuk-casa 9.0.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 (199) hide show
  1. package/README.md +9 -9
  2. package/dist/assets/css/casa.css +1 -1
  3. package/dist/assets/css/casa.css.map +1 -1
  4. package/dist/casa.d.ts +122 -95
  5. package/dist/casa.js +119 -86
  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 +81 -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 +20 -18
  40. package/dist/lib/field.js +35 -48
  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 +11 -10
  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 -27
  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 -19
  139. package/dist/routes/static.js.map +1 -1
  140. package/package.json +19 -18
  141. package/src/casa.js +133 -100
  142. package/src/lib/CasaTemplateLoader.js +24 -19
  143. package/src/lib/JourneyContext.js +138 -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 +69 -58
  154. package/src/lib/index.js +12 -12
  155. package/src/lib/logger.js +9 -9
  156. package/src/lib/mount.js +70 -74
  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 -41
  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 -29
  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/layouts/main.njk +2 -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,18 +222,19 @@ export class PageField {
221
222
  }
222
223
 
223
224
  /**
224
- * Add 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
229
  * @returns {PageField} Chain
230
230
  */
231
231
  validators(items = []) {
232
232
  if (!items.length) {
233
- throw new Error('Calling validators() to get all validators is no longer supported, please use getValidators()');
233
+ throw new Error(
234
+ "Calling validators() to get all validators is no longer supported, please use getValidators()",
235
+ );
234
236
  }
235
- this.#validators = [...this.#validators, ...(items.flat())];
237
+ this.#validators = [...this.#validators, ...items.flat()];
236
238
  return this;
237
239
  }
238
240
 
@@ -246,18 +248,20 @@ export class PageField {
246
248
  }
247
249
 
248
250
  /**
249
- * Add value pre-processors
250
- * 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.
251
253
  *
252
254
  * @param {FieldProcessorFunction[]} items Processor functions
253
255
  * @returns {PageField} Chain
254
256
  */
255
257
  processors(items = []) {
256
258
  if (!items.length) {
257
- throw new Error('Calling processors() to get all processors is no longer supported, please use getProcessors()');
259
+ throw new Error(
260
+ "Calling processors() to get all processors is no longer supported, please use getProcessors()",
261
+ );
258
262
  }
259
263
 
260
- this.#processors = [...this.#processors, ...(items.flat())];
264
+ this.#processors = [...this.#processors, ...items.flat()];
261
265
  return this;
262
266
  }
263
267
 
@@ -271,18 +275,19 @@ export class PageField {
271
275
  }
272
276
 
273
277
  /**
274
- * Add conditions
275
- * All conditions must be met in order for this field to be considered
276
- * "actionable".
278
+ * Add conditions All conditions must be met in order for this field to be
279
+ * considered "actionable".
277
280
  *
278
281
  * @param {ValidatorConditionFunction[]} items Condition functions
279
282
  * @returns {PageField} Chain
280
283
  */
281
284
  conditions(items = []) {
282
285
  if (!items.length) {
283
- throw new Error('Calling conditions() to get all conditions is no longer supported, please use getConditions()');
286
+ throw new Error(
287
+ "Calling conditions() to get all conditions is no longer supported, please use getConditions()",
288
+ );
284
289
  }
285
- this.#conditions = [...this.#conditions, ...(items.flat())];
290
+ this.#conditions = [...this.#conditions, ...items.flat()];
286
291
  return this;
287
292
  }
288
293
 
@@ -311,22 +316,26 @@ export class PageField {
311
316
  // ESLint disabled as `i` is an integer
312
317
  /* eslint-disable security/detect-object-injection */
313
318
  // TODO: Replace `value` with `context.fieldValue` here
314
- let fieldErrors = this.#validators[i].validate(context.fieldValue, context)
319
+ let fieldErrors = this.#validators[i].validate(
320
+ context.fieldValue,
321
+ context,
322
+ );
315
323
  if (!Array.isArray(fieldErrors)) {
316
324
  // Friendly message for developer
317
- 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
+ );
318
328
  }
319
329
 
320
- fieldErrors = fieldErrors.map((e) => e.withContext({
321
- ...context,
322
- validator: this.#validators[i].name,
323
- }));
330
+ fieldErrors = fieldErrors.map((e) =>
331
+ e.withContext({
332
+ ...context,
333
+ validator: this.#validators[i].name,
334
+ }),
335
+ );
324
336
  /* eslint-enable security/detect-object-injection */
325
337
 
326
- errors = [
327
- ...errors,
328
- ...(fieldErrors ?? []),
329
- ];
338
+ errors = [...errors, ...(fieldErrors ?? [])];
330
339
  }
331
340
 
332
341
  return errors;
@@ -432,8 +441,10 @@ export class PageField {
432
441
  * @memberof module:@dwp/govuk-casa
433
442
  * @param {string} name Field name
434
443
  * @param {object} [opts] Options
435
- * @param {boolean} [opts.optional=false] Whether this field is optional
436
- * @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`
437
448
  * @returns {PageField} A PageField
438
449
  */
439
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
+ };