@dwp/govuk-casa 7.0.8 → 8.0.0-beta2

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 (132) hide show
  1. package/README.md +22 -17
  2. package/dist/mjs/esm-wrapper.js +10 -0
  3. package/package.json +55 -80
  4. package/views/casa/components/checkboxes/template.njk +4 -1
  5. package/views/casa/components/date-input/template.njk +3 -3
  6. package/views/casa/components/journey-form/README.md +3 -1
  7. package/views/casa/components/journey-form/template.njk +1 -1
  8. package/views/casa/components/postal-address-object/template.njk +5 -5
  9. package/views/casa/components/radios/template.njk +1 -1
  10. package/views/casa/errors/static.njk +11 -0
  11. package/views/casa/layouts/journey.njk +26 -9
  12. package/views/casa/layouts/main.njk +7 -20
  13. package/views/casa/partials/scripts.njk +8 -3
  14. package/views/casa/partials/styles.njk +2 -2
  15. package/casa.js +0 -208
  16. package/definitions/review-page.js +0 -60
  17. package/dist/casa/css/casa-ie8.css +0 -1
  18. package/dist/casa/css/casa.css +0 -1
  19. package/dist/casa/js/casa.js +0 -1
  20. package/index.d.ts +0 -121
  21. package/lib/ConfigIngestor.js +0 -588
  22. package/lib/GatherModifier.js +0 -14
  23. package/lib/I18n.js +0 -160
  24. package/lib/JourneyContext.d.ts +0 -97
  25. package/lib/JourneyContext.js +0 -552
  26. package/lib/JourneyMap.js +0 -233
  27. package/lib/JourneyRoad.js +0 -330
  28. package/lib/Logger.js +0 -59
  29. package/lib/PageDictionary.d.ts +0 -11
  30. package/lib/PageDirectory.js +0 -77
  31. package/lib/Plan.js +0 -423
  32. package/lib/RoadConverter.js +0 -153
  33. package/lib/UserJourney.js +0 -8
  34. package/lib/Util.js +0 -227
  35. package/lib/Validation.js +0 -20
  36. package/lib/bootstrap/end-session.js +0 -44
  37. package/lib/bootstrap/load-definitions.js +0 -64
  38. package/lib/commonBodyParser.js +0 -15
  39. package/lib/enums.js +0 -6
  40. package/lib/gather-modifiers/index.js +0 -7
  41. package/lib/gather-modifiers/trimPostalAddressObject.js +0 -75
  42. package/lib/gather-modifiers/trimWhitespace.js +0 -16
  43. package/lib/utils/createGetRequest.d.ts +0 -5
  44. package/lib/utils/createGetRequest.js +0 -59
  45. package/lib/utils/index.js +0 -11
  46. package/lib/utils/parseRequest.d.ts +0 -5
  47. package/lib/utils/parseRequest.js +0 -72
  48. package/lib/utils/sanitise.js +0 -74
  49. package/lib/utils/validate.js +0 -32
  50. package/lib/validation/ArrayObjectField.js +0 -49
  51. package/lib/validation/ObjectField.js +0 -53
  52. package/lib/validation/SimpleField.d.ts +0 -12
  53. package/lib/validation/SimpleField.js +0 -46
  54. package/lib/validation/ValidationError.d.ts +0 -14
  55. package/lib/validation/ValidationError.js +0 -170
  56. package/lib/validation/ValidatorFactory.d.ts +0 -32
  57. package/lib/validation/ValidatorFactory.js +0 -91
  58. package/lib/validation/index.js +0 -22
  59. package/lib/validation/processor/flattenErrorArray.js +0 -24
  60. package/lib/validation/processor/queue.js +0 -214
  61. package/lib/validation/processor.js +0 -84
  62. package/lib/validation/rules/README.md +0 -3
  63. package/lib/validation/rules/ValidationRules.d.ts +0 -14
  64. package/lib/validation/rules/dateObject.js +0 -156
  65. package/lib/validation/rules/email.js +0 -44
  66. package/lib/validation/rules/inArray.js +0 -61
  67. package/lib/validation/rules/index.js +0 -23
  68. package/lib/validation/rules/nino.js +0 -48
  69. package/lib/validation/rules/optional.js +0 -14
  70. package/lib/validation/rules/postalAddressObject.js +0 -142
  71. package/lib/validation/rules/regex.js +0 -39
  72. package/lib/validation/rules/required.js +0 -57
  73. package/lib/validation/rules/strlen.js +0 -57
  74. package/lib/validation/rules/wordCount.js +0 -61
  75. package/lib/view-filters/formatDateObject.js +0 -35
  76. package/lib/view-filters/includes.js +0 -10
  77. package/lib/view-filters/index.js +0 -23
  78. package/lib/view-filters/mergeObjectsDeep.js +0 -21
  79. package/lib/view-filters/renderAsAttributes.js +0 -33
  80. package/middleware/errors/404.js +0 -12
  81. package/middleware/errors/catch-all.js +0 -27
  82. package/middleware/errors/index.js +0 -9
  83. package/middleware/headers/config-defaults.js +0 -57
  84. package/middleware/headers/headers.js +0 -40
  85. package/middleware/headers/index.js +0 -9
  86. package/middleware/i18n/i18n.js +0 -56
  87. package/middleware/i18n/index.js +0 -16
  88. package/middleware/index.js +0 -55
  89. package/middleware/mount/index.js +0 -9
  90. package/middleware/mount/mount.js +0 -10
  91. package/middleware/nunjucks/environment.js +0 -57
  92. package/middleware/nunjucks/index.js +0 -8
  93. package/middleware/page/csrf.js +0 -37
  94. package/middleware/page/edit-mode.js +0 -52
  95. package/middleware/page/gather.js +0 -75
  96. package/middleware/page/index.js +0 -103
  97. package/middleware/page/journey-continue.js +0 -157
  98. package/middleware/page/journey-rails.js +0 -102
  99. package/middleware/page/prepare-request.js +0 -77
  100. package/middleware/page/render.js +0 -75
  101. package/middleware/page/skip.js +0 -72
  102. package/middleware/page/utils.js +0 -206
  103. package/middleware/page/validate.js +0 -67
  104. package/middleware/session/expiry.js +0 -95
  105. package/middleware/session/genid.js +0 -18
  106. package/middleware/session/index.js +0 -18
  107. package/middleware/session/init.js +0 -25
  108. package/middleware/session/seed.js +0 -50
  109. package/middleware/session/timeout.js +0 -5
  110. package/middleware/static/asset-versions.js +0 -23
  111. package/middleware/static/index.js +0 -104
  112. package/middleware/static/prepare-assets.js +0 -51
  113. package/middleware/static/serve-assets.js +0 -58
  114. package/middleware/variables/index.js +0 -12
  115. package/middleware/variables/variables.js +0 -35
  116. package/src/browserconfig.xml +0 -5
  117. package/src/js/casa.js +0 -132
  118. package/src/scss/_casaElements.scss +0 -11
  119. package/src/scss/_casaGovukTemplateJinjaPolyfill.scss +0 -39
  120. package/src/scss/_casaMountUrl.scss +0 -8
  121. package/src/scss/casa-ie8.scss +0 -3
  122. package/src/scss/casa.scss +0 -14
  123. package/test/unit/templates/README.md +0 -5
  124. package/test/utils/BaseTestWaypoint.js +0 -106
  125. package/test/utils/concatWaypoints.js +0 -26
  126. package/test/utils/index.js +0 -6
  127. package/test/utils/testTraversal.js +0 -90
  128. package/views/casa/partials/cookie_message.njk +0 -3
  129. package/views/casa/partials/phase_banner_alpha.njk +0 -8
  130. package/views/casa/partials/phase_banner_beta.njk +0 -8
  131. package/views/casa/review/page-block.njk +0 -8
  132. package/views/casa/review/review.njk +0 -47
@@ -1,214 +0,0 @@
1
- const util = require('../../Util.js');
2
- const ValidationError = require('../ValidationError.js');
3
- const rules = require('../rules/index.js');
4
- const flattenErrorArray = require('./flattenErrorArray.js');
5
-
6
- const T_SIMPLE = 'simple';
7
- const T_OBJECT = 'object';
8
- const T_ARRAY_OBJECT = 'array_object';
9
-
10
- /**
11
- * Add a validator object to the processing queue.
12
- *
13
- * @param {Array} queue Queue to which validators will be added
14
- * @param {string} waypointId Waypoint under validation
15
- * @param {PageMeta} pageMeta Meta object representing the page being validated
16
- * @param {object} journeyContext Full JourneyContext
17
- * @param {string} field Field to validate (in square-brace notation)
18
- * @param {import('../SimpleField')} validatorObj Validation attributes to apply
19
- * @returns {void}
20
- */
21
- /* eslint-disable-next-line consistent-return,require-jsdoc */
22
- function queueValidator(queue, waypointId, pageMeta, journeyContext, field, validatorObj) {
23
- // Do not queue if condition is not met
24
- if (validatorObj.condition({
25
- fieldName: util.normalizeHtmlObjectPath(field),
26
- journeyContext,
27
- waypointId,
28
- })) {
29
- switch (validatorObj.type) {
30
- case T_SIMPLE:
31
- /* eslint-disable-next-line no-use-before-define */
32
- return queueSimpleValidator(
33
- queue, waypointId, pageMeta, journeyContext, field, validatorObj,
34
- );
35
- case T_OBJECT:
36
- /* eslint-disable-next-line no-use-before-define */
37
- return queueObjectValidator(
38
- queue, waypointId, pageMeta, journeyContext, field, validatorObj,
39
- );
40
- case T_ARRAY_OBJECT:
41
- /* eslint-disable-next-line no-use-before-define */
42
- return queueArrayObjectValidator(
43
- queue, waypointId, pageMeta, journeyContext, field, validatorObj,
44
- );
45
- default:
46
- throw new Error('Unknown or unspecified validator type');
47
- }
48
- }
49
- }
50
-
51
- /**
52
- * Add a Validation.SimpleField object to the processing queue.
53
- *
54
- * @param {Array} queue Queue to which validators will be added.
55
- * @param {string} waypointId Waypoint under validation.
56
- * @param {PageMeta} pageMeta Meta object representing the page being validated.
57
- * @param {object} journeyContext Full JourneyContext.
58
- * @param {string} field Field to validate (in square-brace notation).
59
- * @param {object} validatorObj Validation attributes to apply.
60
- * @returns {void}
61
- */
62
- function queueSimpleValidator(queue, waypointId, pageMeta, journeyContext, field, validatorObj) {
63
- // Ensure pageMeta.id is defined when extracting data for the waypoint
64
- let pageData;
65
- if (!Object.prototype.hasOwnProperty.call(pageMeta, 'id')) {
66
- pageData = journeyContext.getDataForPage({
67
- id: waypointId,
68
- ...pageMeta,
69
- });
70
- } else {
71
- pageData = journeyContext.getDataForPage(pageMeta);
72
- }
73
-
74
- // For optional fields (i.e. one whose validation rules contains the
75
- // `optional` rule), first check if the field value is present before
76
- // queuing all other rules.
77
- const fieldValue = util.objectPathValue(pageData, field);
78
- if (
79
- validatorObj.validators.some((v) => (v.validate === rules.optional))
80
- && rules.optional(fieldValue)
81
- ) {
82
- return;
83
- }
84
-
85
- validatorObj.validators.forEach((validator) => {
86
- // A more useful exception with reference to field name
87
- if (typeof validator.validate !== 'function') {
88
- throw new Error(`Validator defined on '${field}'' is not a function`);
89
- }
90
-
91
- // Skip `optional` rule as it does not return a Promise, and has already
92
- // been evaluated above.
93
- if (validator.validate === rules.optional) {
94
- return;
95
- }
96
-
97
- // Create context object which allows a validator to optionally looks at
98
- // other data within the page being validated
99
- const dataContext = {
100
- fieldName: field,
101
- journeyContext,
102
- waypointId,
103
- };
104
-
105
- // Determine the name of the validator function so that we can pass it
106
- // back to the template for Anayltics purposes.
107
- const validatorName = (validator.name || validator.validate.name).replace(/^.*?([a-z0-9_]+)$/i, '$1');
108
-
109
- // As well as the validator, we add an immediate `catch()` handler after
110
- // it in order to collect _all_ errors thrown by all validators. Otherise
111
- // `Promise.all()` would reject at the first failure and miss all other
112
- // errors.
113
- queue.push(validator.validate(fieldValue, dataContext).catch((validationError) => {
114
- let err = validationError;
115
- if (err instanceof Error) {
116
- err = ValidationError.make({ errorMsg: err });
117
- } else if (err === undefined) {
118
- err = ValidationError.make({ errorMsg: 'Unknown error' });
119
- }
120
-
121
- let errors;
122
- try {
123
- errors = flattenErrorArray(err);
124
- } catch (ex) {
125
- errors = [ValidationError.make({ errorMsg: ex })];
126
- }
127
-
128
- // Apply current context to each error
129
- errors.forEach((error) => error.withContext({ ...dataContext, validator: validatorName }));
130
-
131
- return Promise.resolve(errors);
132
- }));
133
- });
134
- }
135
-
136
- /**
137
- * Add a Validation.ObjectField object to the queue.
138
- *
139
- * @param {Array} queue Queue to which validators will be added.
140
- * @param {string} waypointId Waypoint under validation.
141
- * @param {PageMeta} pageMeta Meta object representing the page being validated.
142
- * @param {object} journeyContext Full JourneyContext.
143
- * @param {string} field Field to validate (in square-brace notation).
144
- * @param {object} validatorObj Validation attributes to apply.
145
- * @returns {void}
146
- */
147
- function queueObjectValidator(queue, waypointId, pageMeta, journeyContext, field, validatorObj) {
148
- // Add this validator's rules to the queue (if any)
149
- queueSimpleValidator(queue, waypointId, pageMeta, journeyContext, field, validatorObj);
150
-
151
- // Queue the child validator objects
152
- Object.keys(validatorObj.children).forEach((childField) => {
153
- const child = validatorObj.children[childField];
154
- queueValidator(
155
- queue,
156
- waypointId,
157
- pageMeta,
158
- journeyContext,
159
- util.objectPathString(field, childField),
160
- child,
161
- );
162
- });
163
- }
164
-
165
- /**
166
- * Add a Validation.ArrayObjectField object to the queue.
167
- *
168
- * @param {Array} queue Queue to which validators will be added.
169
- * @param {string} waypointId Waypoint under validation.
170
- * @param {PageMeta} pageMeta Meta object representing the page being validated.
171
- * @param {object} journeyContext Full JourneyContext.
172
- * @param {string} field Field to validate (in square-brace notation).
173
- * @param {object} validatorObj Validation attributes to apply.
174
- * @returns {void}
175
- */
176
- function queueArrayObjectValidator(
177
- queue, waypointId, pageMeta, journeyContext, field, validatorObj,
178
- ) {
179
- // Add this validator's rules to the queue (if any)
180
- queueSimpleValidator(queue, waypointId, pageMeta, journeyContext, field, validatorObj);
181
-
182
- // The object at `pageData[field]` should be an array, indexed from 0. If it
183
- // is anything else, it is ignored.
184
- // Some caution is needed here because a non-/empty array will not trigger
185
- // any validations on the fields that _should_ be in objects in that array.
186
- const pageData = journeyContext.getDataForPage(pageMeta);
187
- let arrayObj = util.objectPathValue(pageData, util.objectPathString(field));
188
- if (!Array.isArray(arrayObj)) {
189
- arrayObj = [];
190
- }
191
-
192
- // Cycle through each element in the array and add all validators for each
193
- // one.
194
- arrayObj.forEach((obj, index) => {
195
- Object.keys(validatorObj.children).forEach((childField) => {
196
- const child = validatorObj.children[childField];
197
- queueValidator(
198
- queue,
199
- waypointId,
200
- pageMeta,
201
- journeyContext,
202
- util.objectPathString(`${field}[${index}]`, childField),
203
- child,
204
- );
205
- });
206
- });
207
- }
208
-
209
- module.exports = {
210
- queueValidator,
211
- queueSimpleValidator,
212
- queueObjectValidator,
213
- queueArrayObjectValidator,
214
- };
@@ -1,84 +0,0 @@
1
- const { queueValidator } = require('./processor/queue.js');
2
-
3
- /**
4
- * This is the core function that carries out validation on a page's data.
5
- *
6
- * For objects/array fields, use square-braces syntax.
7
- *
8
- * Parameters:
9
- * string waypointId = The waypoint being validated
10
- * object pageMeta = The meta object representing the page being processed
11
- * JourneyContext journeyContext = The full JourneyContext
12
- * bool reduceErrors = Reduces each field to a single error (default false)
13
- *
14
- * @param {object} params Parameters object as above
15
- * @param {string} params.waypointId Waypoint ID
16
- * @param {object} params.pageMeta Page meta
17
- * @param {Function} params.journeyContext Journey context
18
- * @param {boolean} params.reduceErrors True is errors should be reduced to a single error
19
- * @returns {Promise} Promise
20
- */
21
- // module.exports = (fieldValidators = {}, userData = {}, options = {}) => {
22
- module.exports = ({
23
- waypointId, pageMeta = { fieldValidators: {} }, journeyContext = {}, reduceErrors = false,
24
- } = {}) => {
25
- // Build up a queue of Promises that will be executed on each field
26
- const validatorQueue = [];
27
- Object.keys(pageMeta.fieldValidators).forEach((field) => {
28
- queueValidator(
29
- validatorQueue, waypointId, pageMeta, journeyContext, field, pageMeta.fieldValidators[field],
30
- );
31
- });
32
-
33
- /**
34
- * Reduce the errors to include only the first error per field. Some fields
35
- * have multiple validation rules that may each be violated and thus result
36
- * in their own error messages, which can quickly stack up on larger pages.
37
- *
38
- * @param {object} errors All errors.
39
- * @returns {object} Reduced error list, indexed by field name.
40
- */
41
- function reduceGroupedErrors(errors) {
42
- const reduced = Object.create(null);
43
- Object.keys(errors).forEach((field) => {
44
- reduced[field] = [errors[field][0]];
45
- });
46
- return reduced;
47
- }
48
-
49
- /**
50
- * Gather the array of errors generated by the validation process, into a flat
51
- * object indexed by the field names. This makes it easier to reference errors
52
- * in the front-end template.
53
- *
54
- * @param {Array} errorsList Array of errors.
55
- * @returns {Promise} Promise.
56
- */
57
- function gatherErrors(errorsList) {
58
- let grouped = Object.create(null);
59
- errorsList.forEach((errors) => {
60
- if (Array.isArray(errors)) {
61
- errors.forEach((e) => {
62
- if (!grouped[e.field]) {
63
- grouped[e.field] = [];
64
- }
65
- grouped[e.field].push(e);
66
- });
67
- }
68
- });
69
-
70
- if (reduceErrors) {
71
- grouped = reduceGroupedErrors(grouped);
72
- }
73
-
74
- return Object.keys(grouped).length
75
- ? Promise.reject(grouped)
76
- : Promise.resolve();
77
- }
78
-
79
- // Resulting Promise
80
- if (validatorQueue.length) {
81
- return Promise.all(validatorQueue).then(gatherErrors);
82
- }
83
- return Promise.resolve();
84
- }
@@ -1,3 +0,0 @@
1
- # Validation Rules
2
-
3
- All core **CASA** rules are provided here.
@@ -1,14 +0,0 @@
1
- import ValidationError from '../ValidationError';
2
-
3
- export namespace ValidationRules {
4
- export function dateObject(): Promise<ValidationError | void>;
5
- export function email(): Promise<ValidationError | void>;
6
- export function inArray(): Promise<ValidationError | void>;
7
- export function nino(): Promise<ValidationError | void>;
8
- export function optional(): boolean;
9
- export function postalAddressObject(): Promise<ValidationError | void>;
10
- export function regex(): Promise<ValidationError | void>;
11
- export function required(): Promise<ValidationError | void>;
12
- export function strlen(): Promise<ValidationError | void>;
13
- export function wordCount(): Promise<ValidationError | void>;
14
- }
@@ -1,156 +0,0 @@
1
- /* eslint-disable class-methods-use-this */
2
- /**
3
- * Date object format:
4
- * {
5
- * dd: <string>,
6
- * mm: <string>,
7
- * yyyy: <string>
8
- * }.
9
- *
10
- * Note that the time part of any injected "DateTime" objects will be zero'ed, as
11
- * we are only interested in the date component (minimum day resolution).
12
- *
13
- * Config options:
14
- * string|object errorMsg = Error message to use on validation failure
15
- * object|luxon.Duration afterOffsetFromNow = Date must be after offset from now
16
- * string|object errorMsgAfterOffset = Error for afterOffsetFromNow failure
17
- * object|luxon.Duration beforeOffsetFromNow = Date must be before offset from now
18
- * string|object errorMsgBeforeOffset = Error for beforeOffsetFromNow failure
19
- * bool allowMonthNames = Allow "Jan", "January", etc (default = false)
20
- * bool allowSingleDigitDay = Allow "1" rather than "01" (default = false)
21
- * bool allowSingleDigitMonth = Allow "1" rather than "01" (default = false)
22
- * luxon.DateTime now = Override the notion of "now" (useful for testing)
23
- */
24
- const { DateTime } = require('luxon');
25
- const ValidationError = require('../ValidationError.js');
26
- const ValidatorFactory = require('../ValidatorFactory.js');
27
- const { isObjectType, stringifyInput } = require('../../Util.js');
28
-
29
- class DateObject extends ValidatorFactory {
30
- validate(value, dataContext = {}) {
31
- const config = {
32
- errorMsg: {
33
- inline: 'validation:rule.dateObject.inline',
34
- summary: 'validation:rule.dateObject.summary',
35
- },
36
- errorMsgAfterOffset: {
37
- inline: 'validation:rule.dateObject.afterOffset.inline',
38
- summary: 'validation:rule.dateObject.afterOffset.summary',
39
- },
40
- errorMsgBeforeOffset: {
41
- inline: 'validation:rule.dateObject.beforeOffset.inline',
42
- summary: 'validation:rule.dateObject.beforeOffset.summary',
43
- },
44
- now: DateTime.local(),
45
- allowSingleDigitDay: false,
46
- allowSingleDigitMonth: false,
47
- allowMonthNames: false,
48
- afterOffsetFromNow: undefined,
49
- beforeOffsetFromNow: undefined,
50
- ...this.config,
51
- };
52
-
53
- let valid = false;
54
- let { errorMsg } = config;
55
- let luxonDate;
56
- const NOW = config.now.startOf('day');
57
-
58
- // Accepted formats
59
- let formats = ['dd-MM-yyyy'];
60
- const formatTests = [{
61
- flags: [config.allowSingleDigitDay],
62
- formats: ['d-MM-yyyy'],
63
- }, {
64
- flags: [config.allowSingleDigitDay, config.allowSingleDigitMonth],
65
- formats: ['d-M-yyyy'],
66
- }, {
67
- flags: [config.allowSingleDigitDay, config.allowMonthNames],
68
- formats: ['d-MMM-yyyy', 'd-MMMM-yyyy'],
69
- }, {
70
- flags: [config.allowSingleDigitMonth],
71
- formats: ['dd-M-yyyy'],
72
- }, {
73
- flags: [config.allowMonthNames],
74
- formats: ['dd-MMM-yyyy', 'dd-MMMM-yyyy'],
75
- }];
76
- formatTests.forEach((test) => {
77
- if (test.flags.every((v) => v === true)) {
78
- formats = [...formats, ...test.formats]
79
- }
80
- });
81
-
82
- if (typeof value === 'object') {
83
- formats.find((format) => {
84
- luxonDate = DateTime.fromFormat(
85
- [value.dd, value.mm, value.yyyy].join('-'),
86
- format,
87
- ).startOf('day');
88
-
89
- valid = luxonDate.isValid;
90
-
91
- return valid;
92
- });
93
-
94
- if (luxonDate) {
95
- // Check date is after the specified duration from now.
96
- // Need to use UTC() otherwise DST shifts can affect the calculated offset
97
- if (config.afterOffsetFromNow) {
98
- const offsetDate = NOW.plus(config.afterOffsetFromNow).startOf('day');
99
-
100
- if (luxonDate <= offsetDate) {
101
- valid = false;
102
- errorMsg = config.errorMsgAfterOffset;
103
- }
104
- }
105
-
106
- // Check date is before the specified duration from now
107
- // Need to use UTC() otherwise DST shifts can affect the calculated offset
108
- if (config.beforeOffsetFromNow) {
109
- const offsetDate = NOW.plus(config.beforeOffsetFromNow).startOf('day');
110
-
111
- if (luxonDate >= offsetDate) {
112
- valid = false;
113
- errorMsg = config.errorMsgBeforeOffset;
114
- }
115
- }
116
- }
117
-
118
- // Check presence of each object component (dd, mm, yyyy) in order to log
119
- // which specific parts are in error
120
- errorMsg.focusSuffix = [];
121
- if (!Object.prototype.hasOwnProperty.call(value, 'dd') || !value.dd) {
122
- errorMsg.focusSuffix.push('[dd]');
123
- }
124
- if (!Object.prototype.hasOwnProperty.call(value, 'mm') || !value.mm) {
125
- errorMsg.focusSuffix.push('[mm]');
126
- }
127
- if (!Object.prototype.hasOwnProperty.call(value, 'yyyy') || !value.yyyy) {
128
- errorMsg.focusSuffix.push('[yyyy]');
129
- }
130
-
131
- // If the date is invalid, but not specific parts have been highighted in
132
- // error, then highlight all inputs, focusing on the [dd] first
133
- if (!valid && !errorMsg.focusSuffix.length) {
134
- errorMsg.focusSuffix = ['[dd]', '[mm]', '[yyyy]'];
135
- }
136
- }
137
-
138
- return valid ? Promise.resolve() : Promise.reject(ValidationError.make({
139
- errorMsg,
140
- dataContext,
141
- }));
142
- }
143
-
144
- sanitise(value) {
145
- if (value !== undefined) {
146
- return isObjectType(value) ? {
147
- dd: stringifyInput(value.dd),
148
- mm: stringifyInput(value.mm),
149
- yyyy: stringifyInput(value.yyyy),
150
- } : Object.create(null);
151
- }
152
- return undefined;
153
- }
154
- }
155
-
156
- module.exports = DateObject;
@@ -1,44 +0,0 @@
1
- /* eslint-disable class-methods-use-this */
2
- /**
3
- * Email address.
4
- *
5
- * This is not an exhaustive validation, and is permissive.
6
- *
7
- * Config options:
8
- * string|object errorMsg = Error message to use on validation failure
9
- */
10
-
11
- const { isEmail } = require('validator');
12
- const ValidationError = require('../ValidationError.js');
13
- const ValidatorFactory = require('../ValidatorFactory.js');
14
- const { stringifyInput } = require('../../Util.js');
15
-
16
- class Email extends ValidatorFactory {
17
- validate(value, dataContext = {}) {
18
- let isValid;
19
- try {
20
- isValid = isEmail(value);
21
- } catch (e) {
22
- isValid = false;
23
- }
24
-
25
- const errorMsg = this.config.errorMsg || {
26
- summary: 'validation:rule.email.summary',
27
- inline: 'validation:rule.email.inline',
28
- };
29
-
30
- return isValid ? Promise.resolve() : Promise.reject(ValidationError.make({
31
- errorMsg,
32
- dataContext,
33
- }));
34
- }
35
-
36
- sanitise(value) {
37
- if (value !== undefined) {
38
- return stringifyInput(value);
39
- }
40
- return undefined;
41
- }
42
- }
43
-
44
- module.exports = Email;
@@ -1,61 +0,0 @@
1
- /* eslint-disable class-methods-use-this */
2
- /**
3
- * Test if a value is present in an array.
4
- *
5
- * Config options:
6
- * Array source = Array of values to test against
7
- *
8
- * If the value itself is an array, all values within that array must be present
9
- * in the `source` array in order to pass validation.
10
- */
11
- const ValidationError = require('../ValidationError.js');
12
- const ValidatorFactory = require('../ValidatorFactory.js');
13
- const { stringifyInput, isStringable } = require('../../Util.js');
14
-
15
- class InArray extends ValidatorFactory {
16
- validate(value, dataContext = {}) {
17
- let valid = false;
18
- const source = this.config.source || [];
19
- const errorMsg = this.config.errorMsg || {
20
- inline: 'validation:rule.inArray.inline',
21
- summary: 'validation:rule.inArray.summary',
22
- };
23
-
24
- if (value !== null && typeof value !== 'undefined') {
25
- const search = Array.isArray(value) ? value : [value];
26
- for (let i = 0, l = search.length; i < l; i += 1) {
27
- if (source.indexOf(search[i]) > -1) {
28
- valid = true;
29
- } else {
30
- valid = false;
31
- break;
32
- }
33
- }
34
- }
35
-
36
- return valid ? Promise.resolve() : Promise.reject(ValidationError.make({
37
- errorMsg,
38
- dataContext,
39
- }));
40
- }
41
-
42
- sanitise(value) {
43
- const coerce = (val) => (stringifyInput(val, undefined));
44
-
45
- // Basic stringable
46
- if (isStringable(value)) {
47
- return stringifyInput(value);
48
- }
49
-
50
- // Coerce all elements to Strings.
51
- // This only supports one dimensional array, with stringable element.
52
- if (Array.isArray(value)) {
53
- return value.map(coerce);
54
- }
55
-
56
- // Unsupported value
57
- return undefined;
58
- }
59
- }
60
-
61
- module.exports = InArray;
@@ -1,23 +0,0 @@
1
- const dateObject = require('./dateObject.js');
2
- const email = require('./email.js');
3
- const inArray = require('./inArray.js');
4
- const nino = require('./nino.js');
5
- const optional = require('./optional.js');
6
- const postalAddressObject = require('./postalAddressObject.js');
7
- const regex = require('./regex.js');
8
- const required = require('./required.js');
9
- const strlen = require('./strlen.js');
10
- const wordCount = require('./wordCount.js');
11
-
12
- module.exports = {
13
- dateObject,
14
- email,
15
- inArray,
16
- nino,
17
- optional,
18
- postalAddressObject,
19
- regex,
20
- required,
21
- strlen,
22
- wordCount,
23
- };
@@ -1,48 +0,0 @@
1
- /* eslint-disable class-methods-use-this */
2
- /**
3
- * UK National Insurance number.
4
- *
5
- * Config options:
6
- * string|object errorMsg = Error message to use on validation failure
7
- * boolean allowWhitespace = will permit input values that contain spaces.
8
- *
9
- * Ref:
10
- * https://en.wikipedia.org/wiki/National_Insurance_number#Format
11
- * https://design-system.service.gov.uk/patterns/national-insurance-numbers/
12
- */
13
- const ValidationError = require('../ValidationError.js');
14
- const ValidatorFactory = require('../ValidatorFactory.js');
15
- const { stringifyInput } = require('../../Util.js');
16
-
17
- class Nino extends ValidatorFactory {
18
- validate(value, dataContext = {}) {
19
- const {
20
- allowWhitespace,
21
- errorMsg = {
22
- inline: 'validation:rule.nino.inline',
23
- summary: 'validation:rule.nino.summary',
24
- },
25
- } = this.config;
26
-
27
- if (typeof allowWhitespace !== 'undefined' && typeof allowWhitespace !== 'boolean') {
28
- throw new TypeError(`NINO validation rule option "allowWhitespace" must been a boolean. received ${typeof allowWhitespace}`);
29
- }
30
- const valid = typeof value === 'string'
31
- && value.replace((typeof allowWhitespace !== 'undefined' && allowWhitespace) ? /\u0020/g : '', '')
32
- .match(/^(?!BG|GB|NK|KN|TN|NT|ZZ)[ABCEGHJ-PRSTW-Z][ABCEGHJ-NPRSTW-Z]\d{6}[A-D]$/i);
33
-
34
- return valid ? Promise.resolve() : Promise.reject(ValidationError.make({
35
- errorMsg,
36
- dataContext,
37
- }));
38
- }
39
-
40
- sanitise(value) {
41
- if (value !== undefined) {
42
- return stringifyInput(value);
43
- }
44
- return undefined;
45
- }
46
- }
47
-
48
- module.exports = Nino;
@@ -1,14 +0,0 @@
1
- const Util = require('../../Util.js');
2
-
3
- /**
4
- * This is different to all other rules in that it _must_ return a value
5
- * synchronously. You must not `bind()` this function to create a new one.
6
- *
7
- * @param {any} value Value
8
- * @returns {boolean} Return true if the value is not present
9
- */
10
- function optional(value) {
11
- return Util.isEmpty(value);
12
- }
13
-
14
- module.exports = optional;