@dwp/govuk-casa 8.2.3 → 8.2.4

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 (65) hide show
  1. package/README.md +1 -0
  2. package/dist/casa.d.ts +198 -0
  3. package/dist/casa.js +129 -0
  4. package/dist/lib/CasaTemplateLoader.d.ts +4 -0
  5. package/dist/lib/CasaTemplateLoader.js +5 -0
  6. package/dist/lib/JourneyContext.d.ts +85 -13
  7. package/dist/lib/JourneyContext.js +78 -5
  8. package/dist/lib/Plan.d.ts +122 -49
  9. package/dist/lib/Plan.js +161 -37
  10. package/dist/lib/ValidationError.d.ts +38 -48
  11. package/dist/lib/ValidationError.js +30 -42
  12. package/dist/lib/ValidatorFactory.d.ts +42 -52
  13. package/dist/lib/ValidatorFactory.js +37 -48
  14. package/dist/lib/configuration-ingestor.d.ts +15 -0
  15. package/dist/lib/configuration-ingestor.js +17 -0
  16. package/dist/lib/configure.d.ts +4 -0
  17. package/dist/lib/configure.js +14 -1
  18. package/dist/lib/end-session.d.ts +3 -2
  19. package/dist/lib/end-session.js +2 -1
  20. package/dist/lib/field.d.ts +97 -35
  21. package/dist/lib/field.js +90 -41
  22. package/dist/lib/nunjucks-filters.d.ts +12 -2
  23. package/dist/lib/nunjucks-filters.js +11 -1
  24. package/dist/lib/nunjucks.d.ts +1 -0
  25. package/dist/lib/nunjucks.js +1 -0
  26. package/dist/lib/utils.d.ts +46 -14
  27. package/dist/lib/utils.js +43 -26
  28. package/dist/lib/validators/dateObject.d.ts +75 -1
  29. package/dist/lib/validators/dateObject.js +29 -18
  30. package/dist/lib/validators/email.d.ts +28 -1
  31. package/dist/lib/validators/email.js +20 -9
  32. package/dist/lib/validators/inArray.d.ts +34 -1
  33. package/dist/lib/validators/inArray.js +21 -0
  34. package/dist/lib/validators/index.js +3 -0
  35. package/dist/lib/validators/nino.d.ts +34 -1
  36. package/dist/lib/validators/nino.js +17 -7
  37. package/dist/lib/validators/postalAddressObject.d.ts +68 -1
  38. package/dist/lib/validators/postalAddressObject.js +27 -15
  39. package/dist/lib/validators/regex.d.ts +35 -1
  40. package/dist/lib/validators/regex.js +17 -7
  41. package/dist/lib/validators/required.d.ts +28 -1
  42. package/dist/lib/validators/required.js +19 -6
  43. package/dist/lib/validators/strlen.d.ts +40 -1
  44. package/dist/lib/validators/strlen.js +18 -8
  45. package/dist/lib/validators/wordCount.d.ts +40 -1
  46. package/dist/lib/validators/wordCount.js +18 -8
  47. package/dist/lib/waypoint-url.d.ts +1 -0
  48. package/dist/lib/waypoint-url.js +10 -0
  49. package/dist/middleware/data.js +21 -5
  50. package/dist/middleware/gather-fields.js +1 -0
  51. package/dist/middleware/pre.js +1 -0
  52. package/dist/middleware/steer-journey.js +2 -1
  53. package/dist/middleware/strip-proxy-path.js +6 -2
  54. package/dist/middleware/validate-fields.js +3 -0
  55. package/dist/routes/ancillary.d.ts +16 -5
  56. package/dist/routes/ancillary.js +7 -3
  57. package/dist/routes/journey.d.ts +30 -6
  58. package/dist/routes/journey.js +27 -0
  59. package/dist/routes/static.d.ts +1 -0
  60. package/dist/routes/static.js +2 -1
  61. package/package.json +16 -11
  62. package/views/casa/components/character-count/README.md +1 -1
  63. package/views/casa/components/input/README.md +1 -1
  64. package/views/casa/components/radios/README.md +2 -2
  65. package/views/casa/components/textarea/README.md +1 -1
@@ -10,9 +10,11 @@ const Plan_js_1 = __importDefault(require("./Plan.js"));
10
10
  const logger_js_1 = __importDefault(require("./logger.js"));
11
11
  const utils_js_1 = require("./utils.js");
12
12
  /**
13
+ * @access private
13
14
  * @typedef {import('../casa').ConfigurationOptions} ConfigurationOptions
14
15
  */
15
16
  /**
17
+ * @access private
16
18
  * @typedef {import('../casa').HelmetConfigurator} HelmetConfigurator
17
19
  */
18
20
  const log = (0, logger_js_1.default)('lib:configuration-ingestor');
@@ -20,6 +22,7 @@ const echo = (a) => (a);
20
22
  /**
21
23
  * Validates and sanitises i18n obejct.
22
24
  *
25
+ * @access private
23
26
  * @param {object} i18n Object to validate.
24
27
  * @param {Function} cb Callback function that receives the validated value.
25
28
  * @throws {TypeError} For invalid object.
@@ -35,6 +38,7 @@ exports.validateI18nObject = validateI18nObject;
35
38
  /**
36
39
  * Validates and sanitises i18n directory.
37
40
  *
41
+ * @access private
38
42
  * @param {Array} dirs Array of directories.
39
43
  * @throws {SyntaxError} For invalid directories.
40
44
  * @throws {TypeError} For invalid type.
@@ -55,6 +59,7 @@ exports.validateI18nDirs = validateI18nDirs;
55
59
  /**
56
60
  * Validates and sanitises i18n locales.
57
61
  *
62
+ * @access private
58
63
  * @param {Array} locales Array of locales.
59
64
  * @throws {SyntaxError} For invalid locales.
60
65
  * @throws {TypeError} For invalid type.
@@ -75,6 +80,7 @@ exports.validateI18nLocales = validateI18nLocales;
75
80
  /**
76
81
  * Validates and sanitises mount url.
77
82
  *
83
+ * @access private
78
84
  * @param {string} mountUrl Prefix for all URLs in the browser address bar
79
85
  * @throws {SyntaxError} For invalid URL.
80
86
  * @returns {string|undefined} Sanitised URL.
@@ -92,6 +98,7 @@ exports.validateMountUrl = validateMountUrl;
92
98
  /**
93
99
  * Validates and sanitises sessions object.
94
100
  *
101
+ * @access private
95
102
  * @param {object} session Object to validate.
96
103
  * @param {Function} cb Callback function that receives the validated value.
97
104
  * @throws {TypeError} For invalid object.
@@ -110,6 +117,7 @@ exports.validateSessionObject = validateSessionObject;
110
117
  /**
111
118
  * Validates and sanitises view directory.
112
119
  *
120
+ * @access private
113
121
  * @param {Array} dirs Array of directories.
114
122
  * @throws {SyntaxError} For invalid directories.
115
123
  * @throws {TypeError} For invalid type.
@@ -130,6 +138,7 @@ exports.validateViews = validateViews;
130
138
  /**
131
139
  * Validates and sanitises sessions secret.
132
140
  *
141
+ * @access private
133
142
  * @param {string} secret Session secret.
134
143
  * @throws {ReferenceError} For missing value type.
135
144
  * @throws {TypeError} For invalid value.
@@ -148,6 +157,7 @@ exports.validateSessionSecret = validateSessionSecret;
148
157
  /**
149
158
  * Validates and sanitises sessions ttl.
150
159
  *
160
+ * @access private
151
161
  * @param {number} ttl Session ttl (seconds).
152
162
  * @throws {ReferenceError} For missing value type.
153
163
  * @throws {TypeError} For invalid value.
@@ -163,6 +173,7 @@ exports.validateSessionTtl = validateSessionTtl;
163
173
  /**
164
174
  * Validates and sanitises sessions name.
165
175
  *
176
+ * @access private
166
177
  * @param {string} [name=casa-session] Session name.
167
178
  * @throws {ReferenceError} For missing value type.
168
179
  * @throws {TypeError} For invalid value.
@@ -178,6 +189,7 @@ exports.validateSessionName = validateSessionName;
178
189
  /**
179
190
  * Validates and sanitises sessions secure flag.
180
191
  *
192
+ * @access private
181
193
  * @param {boolean} [secure=false] Session secure flag.
182
194
  * @throws {ReferenceError} For missing value type.
183
195
  * @throws {TypeError} For invalid value.
@@ -193,6 +205,7 @@ exports.validateSessionSecure = validateSessionSecure;
193
205
  /**
194
206
  * Validates and sanitises sessions store.
195
207
  *
208
+ * @access private
196
209
  * @param {Function} store Session store.
197
210
  * @returns {Function} Store.
198
211
  */
@@ -207,6 +220,7 @@ exports.validateSessionStore = validateSessionStore;
207
220
  /**
208
221
  * Validates and sanitises sessions cookie url path.
209
222
  *
223
+ * @access private
210
224
  * @param {string} cookiePath Session cookie url path.
211
225
  * @param {string} defaultPath Default path if none specified.
212
226
  * @returns {string} Cookie path.
@@ -226,6 +240,7 @@ exports.validateSessionCookiePath = validateSessionCookiePath;
226
240
  * Lax
227
241
  * None
228
242
  *
243
+ * @access private
229
244
  * @param {any} cookieSameSite Session cookie "sameSite" flag
230
245
  * @param {any} defaultFlag Default path if none specified
231
246
  * @returns {boolean} cookie path
@@ -356,6 +371,7 @@ exports.validateEvents = validateEvents;
356
371
  /**
357
372
  * Validates helmet configuration function.
358
373
  *
374
+ * @access private
359
375
  * @param {HelmetConfigurator} helmetConfigurator Configuration function
360
376
  * @returns {HelmetConfigurator} Validated configuration function
361
377
  * @throws {TypeError} when passed a non-function
@@ -370,6 +386,7 @@ exports.validateHelmetConfigurator = validateHelmetConfigurator;
370
386
  /**
371
387
  * Ingest, validate, sanitise and manipulate configuration parameters.
372
388
  *
389
+ * @access private
373
390
  * @param {ConfigurationOptions} config Config to ingest.
374
391
  * @throws {Error|SyntaxError|TypeError} For invalid config values.
375
392
  * @returns {object} Immutable config object.
@@ -1,15 +1,19 @@
1
1
  /**
2
+ * @access private
2
3
  * @typedef {import('../casa').ConfigurationOptions} ConfigurationOptions
3
4
  */
4
5
  /**
6
+ * @access private
5
7
  * @typedef {import('../casa').ConfigurationOptions} ConfigureResult
6
8
  */
7
9
  /**
10
+ * @access private
8
11
  * @typedef {import('../casa').Mounter} Mounter
9
12
  */
10
13
  /**
11
14
  * Configure some middleware for use in creating a new CASA app.
12
15
  *
16
+ * @memberof module:@dwp/govuk-casa
13
17
  * @param {ConfigurationOptions} config Configuration options
14
18
  * @returns {ConfigureResult} Result
15
19
  */
@@ -25,17 +25,21 @@ const data_js_1 = __importDefault(require("../middleware/data.js"));
25
25
  const body_parser_js_1 = __importDefault(require("../middleware/body-parser.js"));
26
26
  const csrf_js_1 = __importDefault(require("../middleware/csrf.js"));
27
27
  /**
28
+ * @access private
28
29
  * @typedef {import('../casa').ConfigurationOptions} ConfigurationOptions
29
30
  */
30
31
  /**
32
+ * @access private
31
33
  * @typedef {import('../casa').ConfigurationOptions} ConfigureResult
32
34
  */
33
35
  /**
36
+ * @access private
34
37
  * @typedef {import('../casa').Mounter} Mounter
35
38
  */
36
39
  /**
37
40
  * Configure some middleware for use in creating a new CASA app.
38
41
  *
42
+ * @memberof module:@dwp/govuk-casa
39
43
  * @param {ConfigurationOptions} config Configuration options
40
44
  * @returns {ConfigureResult} Result
41
45
  */
@@ -150,7 +154,16 @@ function configure(config = {}) {
150
154
  res.redirect(302, `${reqPath}${reqParams}`);
151
155
  });
152
156
  }
153
- // Service static assets from the `app` rather than the `router`. The router
157
+ // Capture the mount path of this CASA app, before any parameterised path
158
+ // segments exert influence over `req.baseUrl` in the `router` further below.
159
+ // This can later be used by middleware that wants to use the
160
+ // "unparameterised" version of the request's `baseUrl`, such as the static
161
+ // router's middleware.
162
+ app.use((req, res, next) => {
163
+ req.unparameterisedBaseUrl = req.baseUrl;
164
+ next();
165
+ });
166
+ // Serve static assets from the `app` rather than the `router`. The router
154
167
  // may contain paramaterised path segments which would mean serving static
155
168
  // assets over a dynamic URL each time, thus causing lots of cache misses on
156
169
  // the browser.
@@ -6,8 +6,9 @@
6
6
  * Note: this will not remove the session from server-side storage, which will
7
7
  * instead be left up to the storage mechanism to clean up.
8
8
  *
9
- * @param {object} req HTTP request
9
+ * @memberof module:@dwp/govuk-casa
10
+ * @param {import('express').Request} req HTTP request
10
11
  * @param {Function} next Chain
11
12
  * @returns {void}
12
13
  */
13
- export default function endSession(req: object, next: Function): void;
14
+ export default function endSession(req: import('express').Request, next: Function): void;
@@ -13,7 +13,8 @@ const log = (0, logger_js_1.default)('lib:end-session');
13
13
  * Note: this will not remove the session from server-side storage, which will
14
14
  * instead be left up to the storage mechanism to clean up.
15
15
  *
16
- * @param {object} req HTTP request
16
+ * @memberof module:@dwp/govuk-casa
17
+ * @param {import('express').Request} req HTTP request
17
18
  * @param {Function} next Chain
18
19
  * @returns {void}
19
20
  */
@@ -1,16 +1,56 @@
1
- export default function field(...args: any[]): PageField;
1
+ /**
2
+ * Factory for creating PageField instances.
3
+ *
4
+ * @memberof module:@dwp/govuk-casa
5
+ * @param {string} name Field name
6
+ * @param {object} opts Options
7
+ * @param {boolean} [opts.optional=false] Whether this field is optional
8
+ * @param {boolean} [opts.persist=true] Whether this field will persist in `req.body`
9
+ * @returns {PageField} A PageField
10
+ */
11
+ export default function field(name: string, opts: {
12
+ optional?: boolean | undefined;
13
+ persist?: boolean | undefined;
14
+ }): PageField;
15
+ /**
16
+ * This class is not exposed via the public API. Instances should instead be
17
+ * instantiated through the `field()` factory function.
18
+ *
19
+ * @class
20
+ */
2
21
  export class PageField {
3
- constructor(name: any, { optional, persist }?: any);
4
22
  /**
5
- * For complex fields, we need may need to drill into an object to extract the
23
+ * Create a field.
24
+ *
25
+ * @param {string} name Field name
26
+ * @param {object} opts Options
27
+ * @param {boolean} [opts.optional=false] Whether this field is optional
28
+ * @param {boolean} [opts.persist=true] Whether this field will persist in `req.body`
29
+ */
30
+ constructor(name: string, { optional, persist }?: {
31
+ optional?: boolean | undefined;
32
+ persist?: boolean | undefined;
33
+ });
34
+ /**
35
+ * Extract this field's value from the given object.
36
+ *
37
+ * For complex fields, we may need to drill into an object to extract the
6
38
  * value.
7
39
  *
8
40
  * @param {object} obj Object from which to extract the value
9
41
  * @returns {any} Value extracted from object
10
- * @throws {Error} When run on a complex field
42
+ * @throws {Error} When run on a complex field (not yet supported)
11
43
  */
12
44
  getValue(obj?: object): any;
13
- putValue(obj?: any, value?: undefined): PageField;
45
+ /**
46
+ * Store this field's value in the given object, using its name as the key.
47
+ *
48
+ * @param {object} obj Object from which to extract the value
49
+ * @param {any} value Value to be stored
50
+ * @returns {any} Value extracted from object
51
+ * @throws {Error} When run on a complex field (not yet supported)
52
+ */
53
+ putValue(obj?: object, value?: any): any;
14
54
  get name(): string;
15
55
  get meta(): object;
16
56
  /**
@@ -18,60 +58,82 @@ export class PageField {
18
58
  * Some validators will include a `sanitise()` method which will be run at the
19
59
  * same time as other "processors".
20
60
  *
21
- * @param {ValidateFunction[]} items Validation functions
22
- * @returns {PageField | ValidateFunction[]} Chain or return all validators
61
+ * @param {Validator[]} items Validation functions
62
+ * @returns {PageField | Validator[]} Chain or return all validators
23
63
  */
24
- validators(items?: ValidateFunction[]): PageField | ValidateFunction[];
64
+ validators(items?: Validator[]): PageField | Validator[];
25
65
  /**
26
66
  * Add/get value pre-processors
27
67
  * This is most often used to sanitise values to a particular data type.
28
68
  *
29
- * @param {ProcessorFunction[]} items Processor functions
30
- * @returns {PageField | ProcessorFunction[]} Chain or return all processors
69
+ * @param {FieldProcessorFunction[]} items Processor functions
70
+ * @returns {PageField | FieldProcessorFunction[]} Chain or return all processors
31
71
  */
32
- processors(items?: ProcessorFunction[]): PageField | ProcessorFunction[];
72
+ processors(items?: FieldProcessorFunction[]): PageField | FieldProcessorFunction[];
33
73
  /**
34
74
  * Add/get conditions
35
75
  * All conditions must be met in order for this field to be considered
36
76
  * "actionable".
37
77
  *
38
- * @param {ConditionFunction[]} items Condition functions
39
- * @returns {PageField | ConditionFunction[]} Chain or return all conditions
78
+ * @param {ValidatorConditionFunction[]} items Condition functions
79
+ * @returns {PageField | ValidatorConditionFunction[]} Chain or return all conditions
40
80
  */
41
- conditions(items?: ConditionFunction[]): PageField | ConditionFunction[];
81
+ conditions(items?: ValidatorConditionFunction[]): PageField | ValidatorConditionFunction[];
42
82
  /**
43
83
  * Run all validators and return array of errors, if applicable.
44
84
  *
45
85
  * @param {any} value Value to validate
46
- * @param {ValidateContext} context Contextual information
86
+ * @param {ValidateContext} context Contextual validation information
47
87
  * @returns {ValidationError[]} Errors, or an empty array if all valid
48
88
  */
49
- runValidators(value: any, context?: any): ValidationError[];
89
+ runValidators(value: any, context?: ValidateContext): ValidationError[];
90
+ /**
91
+ * Apply all the processors to the given value.
92
+ *
93
+ * @param {any} value Value to process
94
+ * @returns {any} Processed value
95
+ */
50
96
  applyProcessors(value: any): any;
51
97
  /**
52
- * Apply all conditions to get the resulting boolean
98
+ * All conditions must return true to be considered a successful test.
53
99
  *
54
- * @param {object} params Parameters
55
- * @param {string} params.fieldValue Field value
56
- * @param {string} params.waypoint Waypoint
57
- * @param {object} params.journeyContext JourneyContext
100
+ * @param {ValidateContext} context Contextual validation information
58
101
  * @returns {boolean} True if all conditions pass
59
102
  */
60
- testConditions({ fieldValue, waypoint, journeyContext }: {
61
- fieldValue: string;
62
- waypoint: string;
63
- journeyContext: object;
64
- }): boolean;
65
- validator(validator: any): any[] | PageField;
66
- processor(processor: any): PageField | ProcessorFunction[];
67
- condition(condition: any): PageField | ConditionFunction[];
68
- if(...args: any[]): PageField | ConditionFunction[];
103
+ testConditions({ fieldValue, waypoint, journeyContext }: ValidateContext): boolean;
104
+ /**
105
+ * Add a single validator.
106
+ *
107
+ * @param {Validator} validator Validation function
108
+ * @returns {PageField} Chain
109
+ */
110
+ validator(validator: Validator): PageField;
111
+ /**
112
+ * Add a single pre-processors
113
+ *
114
+ * @param {FieldProcessorFunction} processor Processor function
115
+ * @returns {PageField} Chain
116
+ */
117
+ processor(processor: FieldProcessorFunction): PageField;
118
+ /**
119
+ * Add a single condition.
120
+ *
121
+ * @param {ValidatorConditionFunction} condition Condition function
122
+ * @returns {PageField} Chain
123
+ */
124
+ condition(condition: ValidatorConditionFunction): PageField;
125
+ /**
126
+ * Alias for `conditions()`.
127
+ *
128
+ * @param {...ValidatorConditionFunction} args Condition functions
129
+ * @returns {PageField} Chain
130
+ */
131
+ if(...args: ValidatorConditionFunction[]): PageField;
69
132
  #private;
70
133
  }
71
134
  export type JourneyContext = import('./index').JourneyContext;
72
- export type Validator = import('./index').Validator;
73
- export type ValidateFunction = import('./index').ValidateFunction;
74
- export type ValidateContext = import('./index').ValidateContext;
135
+ export type Validator = import('../casa').Validator;
136
+ export type ValidateContext = import('../casa').ValidateContext;
137
+ export type ValidatorConditionFunction = import('../casa').ValidatorConditionFunction;
138
+ export type FieldProcessorFunction = import('../casa').FieldProcessorFunction;
75
139
  export type ValidationError = import('./index').ValidationError;
76
- export type ProcessorFunction = (value: any) => any;
77
- export type ConditionFunction = (context: Object, fieldName: string, fieldValue: any, waypoint: string, waypointId: string, journeyContext: JourneyContext) => boolean;
package/dist/lib/field.js CHANGED
@@ -20,57 +20,63 @@ const lodash_1 = __importDefault(require("lodash"));
20
20
  const utils_js_1 = require("./utils.js");
21
21
  const { isFunction } = lodash_1.default;
22
22
  /**
23
+ * @access private
23
24
  * @typedef {import('./index').JourneyContext} JourneyContext
24
25
  */
25
26
  /**
26
- * @typedef {import('./index').Validator} Validator
27
+ * @access private
28
+ * @typedef {import('../casa').Validator} Validator
27
29
  */
28
30
  /**
29
- * @typedef {import('./index').ValidateFunction} ValidateFunction
31
+ * @access private
32
+ * @typedef {import('../casa').ValidateContext} ValidateContext
30
33
  */
31
34
  /**
32
- * @typedef {import('./index').ValidateContext} ValidateContext
35
+ * @access private
36
+ * @typedef {import('../casa').ValidatorConditionFunction} ValidatorConditionFunction
33
37
  */
34
38
  /**
35
- * @typedef {import('./index').ValidationError} ValidationError
36
- */
37
- /**
38
- * @callback ProcessorFunction
39
- * @param {any} value Value to be processed
40
- * @returns {any}
39
+ * @access private
40
+ * @typedef {import('../casa').FieldProcessorFunction} FieldProcessorFunction
41
41
  */
42
42
  /**
43
- * @callback ConditionFunction
44
- * @param {Object} context Value to be processed
45
- * @param {string} context.fieldName Field name
46
- * @param {any} context.fieldValue Field value
47
- * @param {string} context.waypoint Waypoint
48
- * @param {string} context.waypointId [DEPRECATED] Waypoint (for backwards compatibility with v7)
49
- * @param {JourneyContext} journeyContext Journey Context
50
- * @returns {boolean} True if the validators should be run
43
+ * @access private
44
+ * @typedef {import('./index').ValidationError} ValidationError
51
45
  */
52
46
  // Quick check to see if the field name corresponds to a non-primitive complex
53
47
  // type. For example, `my_field[nested]`.
54
48
  const reComplexType = /\[/;
55
49
  const reInvalidName = /[^a-z0-9_.\-[\]]/i;
56
- // This is never exposed via a public API, and instead users are encouraged to
57
- // use the `field()` factory instead
50
+ /**
51
+ * This class is not exposed via the public API. Instances should instead be
52
+ * instantiated through the `field()` factory function.
53
+ *
54
+ * @class
55
+ */
58
56
  class PageField {
57
+ /**
58
+ * Create a field.
59
+ *
60
+ * @param {string} name Field name
61
+ * @param {object} opts Options
62
+ * @param {boolean} [opts.optional=false] Whether this field is optional
63
+ * @param {boolean} [opts.persist=true] Whether this field will persist in `req.body`
64
+ */
59
65
  constructor(name, { optional = false, persist = true } = Object.create(null)) {
60
- /*
66
+ /**
61
67
  * @type {string}
62
68
  */
63
69
  _PageField_name.set(this, void 0);
64
70
  /**
65
- * @type {ProcessorFunction[]}
71
+ * @type {FieldProcessorFunction[]}
66
72
  */
67
73
  _PageField_processors.set(this, void 0);
68
74
  /**
69
- * @type {ValidateFunction[]}
75
+ * @type {Validator[]}
70
76
  */
71
77
  _PageField_validators.set(this, void 0);
72
78
  /**
73
- * @type {ConditionFunction[]}
79
+ * @type {ValidatorConditionFunction[]}
74
80
  */
75
81
  _PageField_conditions.set(this, void 0);
76
82
  /**
@@ -94,12 +100,14 @@ class PageField {
94
100
  }, "f");
95
101
  }
96
102
  /**
97
- * For complex fields, we need may need to drill into an object to extract the
103
+ * Extract this field's value from the given object.
104
+ *
105
+ * For complex fields, we may need to drill into an object to extract the
98
106
  * value.
99
107
  *
100
108
  * @param {object} obj Object from which to extract the value
101
109
  * @returns {any} Value extracted from object
102
- * @throws {Error} When run on a complex field
110
+ * @throws {Error} When run on a complex field (not yet supported)
103
111
  */
104
112
  getValue(obj = Object.create(null)) {
105
113
  if (!__classPrivateFieldGet(this, _PageField_meta, "f").complex) {
@@ -107,6 +115,14 @@ class PageField {
107
115
  }
108
116
  throw new Error('Not yet supporting complex field types');
109
117
  }
118
+ /**
119
+ * Store this field's value in the given object, using its name as the key.
120
+ *
121
+ * @param {object} obj Object from which to extract the value
122
+ * @param {any} value Value to be stored
123
+ * @returns {any} Value extracted from object
124
+ * @throws {Error} When run on a complex field (not yet supported)
125
+ */
110
126
  putValue(obj = Object.create(null), value = undefined) {
111
127
  if (!__classPrivateFieldGet(this, _PageField_meta, "f").complex) {
112
128
  /* eslint-disable-next-line no-param-reassign */
@@ -127,8 +143,8 @@ class PageField {
127
143
  * Some validators will include a `sanitise()` method which will be run at the
128
144
  * same time as other "processors".
129
145
  *
130
- * @param {ValidateFunction[]} items Validation functions
131
- * @returns {PageField | ValidateFunction[]} Chain or return all validators
146
+ * @param {Validator[]} items Validation functions
147
+ * @returns {PageField | Validator[]} Chain or return all validators
132
148
  */
133
149
  validators(items = []) {
134
150
  if (!items.length) {
@@ -141,8 +157,8 @@ class PageField {
141
157
  * Add/get value pre-processors
142
158
  * This is most often used to sanitise values to a particular data type.
143
159
  *
144
- * @param {ProcessorFunction[]} items Processor functions
145
- * @returns {PageField | ProcessorFunction[]} Chain or return all processors
160
+ * @param {FieldProcessorFunction[]} items Processor functions
161
+ * @returns {PageField | FieldProcessorFunction[]} Chain or return all processors
146
162
  */
147
163
  processors(items = []) {
148
164
  if (!items.length) {
@@ -156,8 +172,8 @@ class PageField {
156
172
  * All conditions must be met in order for this field to be considered
157
173
  * "actionable".
158
174
  *
159
- * @param {ConditionFunction[]} items Condition functions
160
- * @returns {PageField | ConditionFunction[]} Chain or return all conditions
175
+ * @param {ValidatorConditionFunction[]} items Condition functions
176
+ * @returns {PageField | ValidatorConditionFunction[]} Chain or return all conditions
161
177
  */
162
178
  conditions(items = []) {
163
179
  if (!items.length) {
@@ -171,7 +187,7 @@ class PageField {
171
187
  * Run all validators and return array of errors, if applicable.
172
188
  *
173
189
  * @param {any} value Value to validate
174
- * @param {ValidateContext} context Contextual information
190
+ * @param {ValidateContext} context Contextual validation information
175
191
  * @returns {ValidationError[]} Errors, or an empty array if all valid
176
192
  */
177
193
  runValidators(value, context = Object.create(null)) {
@@ -182,6 +198,8 @@ class PageField {
182
198
  }
183
199
  // Skip validation if conditions are not met
184
200
  // We duplicate value in context.fieldValue for historical reasons
201
+ // @todo explain these historical reasons! And deprecate the need for
202
+ // `value` altogether
185
203
  context.fieldValue = (_a = context.fieldValue) !== null && _a !== void 0 ? _a : value;
186
204
  if (!this.testConditions(context)) {
187
205
  return [];
@@ -190,6 +208,7 @@ class PageField {
190
208
  for (let i = 0, l = __classPrivateFieldGet(this, _PageField_validators, "f").length; i < l; i++) {
191
209
  // ESLint disabled as `i` is an integer
192
210
  /* eslint-disable security/detect-object-injection */
211
+ // TODO: Replace `value` with `context.fieldValue` here
193
212
  const fieldErrors = __classPrivateFieldGet(this, _PageField_validators, "f")[i].validate(value, context).map((e) => e.withContext(Object.assign(Object.assign({}, context), { validator: __classPrivateFieldGet(this, _PageField_validators, "f")[i].name })));
194
213
  /* eslint-enable security/detect-object-injection */
195
214
  errors = [
@@ -199,7 +218,7 @@ class PageField {
199
218
  }
200
219
  return errors;
201
220
  }
202
- /*
221
+ /**
203
222
  * Apply all the processors to the given value.
204
223
  *
205
224
  * @param {any} value Value to process
@@ -225,12 +244,9 @@ class PageField {
225
244
  return processedValue;
226
245
  }
227
246
  /**
228
- * Apply all conditions to get the resulting boolean
247
+ * All conditions must return true to be considered a successful test.
229
248
  *
230
- * @param {object} params Parameters
231
- * @param {string} params.fieldValue Field value
232
- * @param {string} params.waypoint Waypoint
233
- * @param {object} params.journeyContext JourneyContext
249
+ * @param {ValidateContext} context Contextual validation information
234
250
  * @returns {boolean} True if all conditions pass
235
251
  */
236
252
  testConditions({ fieldValue, waypoint, journeyContext }) {
@@ -250,23 +266,56 @@ class PageField {
250
266
  return result;
251
267
  }
252
268
  /* ---------------------------------------------------------------- aliases */
269
+ /**
270
+ * Add a single validator.
271
+ *
272
+ * @param {Validator} validator Validation function
273
+ * @returns {PageField} Chain
274
+ */
253
275
  validator(validator) {
254
276
  return this.validators([validator]);
255
277
  }
278
+ /**
279
+ * Add a single pre-processors
280
+ *
281
+ * @param {FieldProcessorFunction} processor Processor function
282
+ * @returns {PageField} Chain
283
+ */
256
284
  processor(processor) {
257
285
  return this.processors([processor]);
258
286
  }
287
+ /**
288
+ * Add a single condition.
289
+ *
290
+ * @param {ValidatorConditionFunction} condition Condition function
291
+ * @returns {PageField} Chain
292
+ */
259
293
  condition(condition) {
260
294
  return this.conditions([condition]);
261
295
  }
296
+ /**
297
+ * Alias for `conditions()`.
298
+ *
299
+ * @param {...ValidatorConditionFunction} args Condition functions
300
+ * @returns {PageField} Chain
301
+ */
262
302
  if(...args) {
263
303
  return this.conditions(...args);
264
304
  }
265
305
  }
266
306
  exports.PageField = PageField;
267
307
  _PageField_name = new WeakMap(), _PageField_processors = new WeakMap(), _PageField_validators = new WeakMap(), _PageField_conditions = new WeakMap(), _PageField_meta = new WeakMap();
268
- // Factory for convenience
269
- function field(...args) {
270
- return new PageField(...args);
308
+ /**
309
+ * Factory for creating PageField instances.
310
+ *
311
+ * @memberof module:@dwp/govuk-casa
312
+ * @param {string} name Field name
313
+ * @param {object} opts Options
314
+ * @param {boolean} [opts.optional=false] Whether this field is optional
315
+ * @param {boolean} [opts.persist=true] Whether this field will persist in `req.body`
316
+ * @returns {PageField} A PageField
317
+ */
318
+ function field(name, opts) {
319
+ return new PageField(name, opts);
271
320
  }
272
321
  exports.default = field;
@@ -1,5 +1,13 @@
1
1
  export function mergeObjects(...objects: any[]): object;
2
- export function includes(source?: any[], search?: string): boolean;
2
+ /**
3
+ * Determine whether a value exists in a list.
4
+ *
5
+ * @memberof NunjucksFilters
6
+ * @param {any[]} source List of items to search
7
+ * @param {any} search Item to search within the `source`
8
+ * @returns {boolean} True if the search item was found
9
+ */
10
+ export function includes(source?: any[], search?: any): boolean;
3
11
  /**
4
12
  * Format a given date.
5
13
  *
@@ -8,6 +16,7 @@ export function includes(source?: any[], search?: string): boolean;
8
16
  * `date` may be any of the following types:
9
17
  * object - {dd:'', mm:'', yyyy:''}
10
18
  *
19
+ * @memberof NunjucksFilters
11
20
  * @param {object} date Date (see supported formats above)
12
21
  * @param {object} config Holds locale
13
22
  * @returns {string} Formatted date
@@ -20,7 +29,8 @@ export function formatDateObject(date: object, config?: object): string;
20
29
  * Given: {class: 'basic', 'data-ga': 3}
21
30
  * Output: class="basic" data-ga="3"
22
31
  *
23
- * @param {object} attrsObject Attributes object (in name:value pairs)
32
+ * @memberof NunjucksFilters
33
+ * @param {object} attrsObject Attributes object (in name:value pairs)
24
34
  * @returns {string} Formatted
25
35
  */
26
36
  export function renderAsAttributes(attrsObject: object): string;