@dwp/govuk-casa 7.0.6 → 8.0.0-alpha1
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.
- package/README.md +22 -17
- package/dist/{casa → assets}/css/casa-ie8.css +1 -1
- package/dist/assets/css/casa.css +1 -0
- package/dist/casa.d.ts +10 -0
- package/dist/casa.js +44 -0
- package/dist/lib/CasaTemplateLoader.d.ts +19 -0
- package/dist/lib/CasaTemplateLoader.js +57 -0
- package/dist/lib/JourneyContext.d.ts +255 -0
- package/dist/lib/JourneyContext.js +681 -0
- package/dist/lib/MutableRouter.d.ts +155 -0
- package/dist/lib/MutableRouter.js +272 -0
- package/dist/lib/Plan.d.ts +119 -0
- package/dist/lib/Plan.js +382 -0
- package/dist/lib/ValidationError.d.ts +70 -0
- package/dist/lib/ValidationError.js +156 -0
- package/dist/lib/ValidatorFactory.d.ts +24 -0
- package/dist/lib/ValidatorFactory.js +87 -0
- package/dist/lib/configure.d.ts +205 -0
- package/dist/lib/configure.js +215 -0
- package/dist/lib/dirname.cjs +1 -0
- package/dist/lib/end-session.d.ts +12 -0
- package/dist/lib/end-session.js +24 -0
- package/dist/lib/field.d.ts +79 -0
- package/dist/lib/field.js +223 -0
- package/dist/lib/logger.d.ts +8 -0
- package/dist/lib/logger.js +19 -0
- package/dist/lib/nunjucks-filters.d.ts +26 -0
- package/dist/lib/nunjucks-filters.js +112 -0
- package/dist/lib/nunjucks.d.ts +22 -0
- package/dist/lib/nunjucks.js +49 -0
- package/dist/lib/utils.d.ts +22 -0
- package/dist/lib/utils.js +44 -0
- package/dist/lib/validators/dateObject.d.ts +4 -0
- package/dist/lib/validators/dateObject.js +135 -0
- package/dist/lib/validators/email.d.ts +4 -0
- package/dist/lib/validators/email.js +46 -0
- package/dist/lib/validators/inArray.d.ts +4 -0
- package/dist/lib/validators/inArray.js +60 -0
- package/dist/lib/validators/index.d.ts +21 -0
- package/dist/lib/validators/index.js +47 -0
- package/dist/lib/validators/nino.d.ts +4 -0
- package/dist/lib/validators/nino.js +46 -0
- package/dist/lib/validators/postalAddressObject.d.ts +4 -0
- package/dist/lib/validators/postalAddressObject.js +123 -0
- package/dist/lib/validators/regex.d.ts +4 -0
- package/dist/lib/validators/regex.js +40 -0
- package/dist/lib/validators/required.d.ts +4 -0
- package/dist/lib/validators/required.js +56 -0
- package/dist/lib/validators/strlen.d.ts +4 -0
- package/dist/lib/validators/strlen.js +51 -0
- package/dist/lib/validators/wordCount.d.ts +5 -0
- package/dist/lib/validators/wordCount.js +54 -0
- package/dist/lib/waypoint-url.d.ts +17 -0
- package/dist/lib/waypoint-url.js +46 -0
- package/dist/middleware/body-parser.d.ts +1 -0
- package/dist/middleware/body-parser.js +24 -0
- package/dist/middleware/csrf.d.ts +1 -0
- package/dist/middleware/csrf.js +31 -0
- package/dist/middleware/data.d.ts +6 -0
- package/dist/middleware/data.js +53 -0
- package/dist/middleware/dirname.cjs +1 -0
- package/dist/middleware/gather-fields.d.ts +5 -0
- package/dist/middleware/gather-fields.js +39 -0
- package/dist/middleware/i18n.d.ts +4 -0
- package/dist/middleware/i18n.js +87 -0
- package/dist/middleware/post.d.ts +1 -0
- package/dist/middleware/post.js +42 -0
- package/dist/middleware/pre.d.ts +3 -0
- package/dist/middleware/pre.js +38 -0
- package/dist/middleware/progress-journey.d.ts +6 -0
- package/dist/middleware/progress-journey.js +82 -0
- package/dist/middleware/sanitise-fields.d.ts +5 -0
- package/dist/middleware/sanitise-fields.js +48 -0
- package/dist/middleware/session.d.ts +10 -0
- package/dist/middleware/session.js +115 -0
- package/dist/middleware/skip-waypoint.d.ts +5 -0
- package/dist/middleware/skip-waypoint.js +40 -0
- package/dist/middleware/steer-journey.d.ts +6 -0
- package/dist/middleware/steer-journey.js +44 -0
- package/dist/middleware/validate-fields.d.ts +7 -0
- package/dist/middleware/validate-fields.js +76 -0
- package/dist/mjs/esm-wrapper.js +10 -0
- package/dist/mjs/package.json +3 -0
- package/dist/package.json +3 -0
- package/dist/routes/ancillary.d.ts +4 -0
- package/dist/routes/ancillary.js +19 -0
- package/dist/routes/dirname.cjs +1 -0
- package/dist/routes/journey.d.ts +8 -0
- package/dist/routes/journey.js +130 -0
- package/dist/routes/static.d.ts +26 -0
- package/dist/routes/static.js +67 -0
- package/package.json +45 -86
- package/views/casa/components/checkboxes/template.njk +4 -1
- package/views/casa/components/date-input/template.njk +3 -3
- package/views/casa/components/journey-form/README.md +3 -1
- package/views/casa/components/journey-form/template.njk +1 -1
- package/views/casa/components/postal-address-object/template.njk +5 -5
- package/views/casa/components/radios/template.njk +1 -1
- package/views/casa/layouts/journey.njk +26 -9
- package/views/casa/layouts/main.njk +6 -19
- package/views/casa/partials/scripts.njk +8 -3
- package/views/casa/partials/styles.njk +2 -2
- package/casa.js +0 -208
- package/definitions/review-page.js +0 -60
- package/dist/casa/css/casa.css +0 -1
- package/dist/casa/js/casa.js +0 -1
- package/index.d.ts +0 -121
- package/lib/ConfigIngestor.js +0 -588
- package/lib/GatherModifier.js +0 -14
- package/lib/I18n.js +0 -160
- package/lib/JourneyContext.d.ts +0 -97
- package/lib/JourneyContext.js +0 -552
- package/lib/JourneyMap.js +0 -233
- package/lib/JourneyRoad.js +0 -330
- package/lib/Logger.js +0 -59
- package/lib/PageDictionary.d.ts +0 -11
- package/lib/PageDirectory.js +0 -77
- package/lib/Plan.js +0 -423
- package/lib/RoadConverter.js +0 -153
- package/lib/UserJourney.js +0 -8
- package/lib/Util.js +0 -227
- package/lib/Validation.js +0 -20
- package/lib/bootstrap/end-session.js +0 -44
- package/lib/bootstrap/load-definitions.js +0 -64
- package/lib/commonBodyParser.js +0 -15
- package/lib/enums.js +0 -6
- package/lib/gather-modifiers/index.js +0 -7
- package/lib/gather-modifiers/trimPostalAddressObject.js +0 -75
- package/lib/gather-modifiers/trimWhitespace.js +0 -16
- package/lib/utils/createGetRequest.d.ts +0 -5
- package/lib/utils/createGetRequest.js +0 -59
- package/lib/utils/index.js +0 -11
- package/lib/utils/parseRequest.d.ts +0 -5
- package/lib/utils/parseRequest.js +0 -72
- package/lib/utils/sanitise.js +0 -74
- package/lib/utils/validate.js +0 -32
- package/lib/validation/ArrayObjectField.js +0 -49
- package/lib/validation/ObjectField.js +0 -53
- package/lib/validation/SimpleField.d.ts +0 -11
- package/lib/validation/SimpleField.js +0 -46
- package/lib/validation/ValidationError.d.ts +0 -14
- package/lib/validation/ValidationError.js +0 -170
- package/lib/validation/ValidatorFactory.d.ts +0 -32
- package/lib/validation/ValidatorFactory.js +0 -91
- package/lib/validation/index.js +0 -22
- package/lib/validation/processor/flattenErrorArray.js +0 -24
- package/lib/validation/processor/queue.js +0 -214
- package/lib/validation/processor.js +0 -84
- package/lib/validation/rules/README.md +0 -3
- package/lib/validation/rules/ValidationRules.d.ts +0 -22
- package/lib/validation/rules/dateObject.js +0 -156
- package/lib/validation/rules/email.js +0 -44
- package/lib/validation/rules/inArray.js +0 -61
- package/lib/validation/rules/index.js +0 -23
- package/lib/validation/rules/nino.js +0 -48
- package/lib/validation/rules/optional.js +0 -14
- package/lib/validation/rules/postalAddressObject.js +0 -142
- package/lib/validation/rules/regex.js +0 -39
- package/lib/validation/rules/required.js +0 -57
- package/lib/validation/rules/strlen.js +0 -57
- package/lib/validation/rules/wordCount.js +0 -61
- package/lib/view-filters/formatDateObject.js +0 -35
- package/lib/view-filters/includes.js +0 -10
- package/lib/view-filters/index.js +0 -23
- package/lib/view-filters/mergeObjectsDeep.js +0 -21
- package/lib/view-filters/renderAsAttributes.js +0 -33
- package/middleware/errors/404.js +0 -12
- package/middleware/errors/catch-all.js +0 -27
- package/middleware/errors/index.js +0 -9
- package/middleware/headers/config-defaults.js +0 -57
- package/middleware/headers/headers.js +0 -40
- package/middleware/headers/index.js +0 -9
- package/middleware/i18n/i18n.js +0 -56
- package/middleware/i18n/index.js +0 -16
- package/middleware/index.js +0 -55
- package/middleware/mount/index.js +0 -9
- package/middleware/mount/mount.js +0 -10
- package/middleware/nunjucks/environment.js +0 -57
- package/middleware/nunjucks/index.js +0 -8
- package/middleware/page/csrf.js +0 -37
- package/middleware/page/edit-mode.js +0 -52
- package/middleware/page/gather.js +0 -75
- package/middleware/page/index.js +0 -103
- package/middleware/page/journey-continue.js +0 -157
- package/middleware/page/journey-rails.js +0 -102
- package/middleware/page/prepare-request.js +0 -77
- package/middleware/page/render.js +0 -75
- package/middleware/page/skip.js +0 -72
- package/middleware/page/utils.js +0 -206
- package/middleware/page/validate.js +0 -67
- package/middleware/session/expiry.js +0 -95
- package/middleware/session/genid.js +0 -18
- package/middleware/session/index.js +0 -18
- package/middleware/session/init.js +0 -25
- package/middleware/session/seed.js +0 -50
- package/middleware/session/timeout.js +0 -5
- package/middleware/static/asset-versions.js +0 -23
- package/middleware/static/index.js +0 -104
- package/middleware/static/prepare-assets.js +0 -51
- package/middleware/static/serve-assets.js +0 -58
- package/middleware/variables/index.js +0 -12
- package/middleware/variables/variables.js +0 -35
- package/src/browserconfig.xml +0 -5
- package/src/js/casa.js +0 -132
- package/src/scss/_casaElements.scss +0 -11
- package/src/scss/_casaGovukTemplateJinjaPolyfill.scss +0 -39
- package/src/scss/_casaMountUrl.scss +0 -8
- package/src/scss/casa-ie8.scss +0 -3
- package/src/scss/casa.scss +0 -14
- package/test/unit/templates/README.md +0 -5
- package/test/utils/BaseTestWaypoint.js +0 -106
- package/test/utils/concatWaypoints.js +0 -26
- package/test/utils/index.js +0 -6
- package/test/utils/testTraversal.js +0 -90
- package/views/casa/partials/cookie_message.njk +0 -3
- package/views/casa/partials/phase_banner_alpha.njk +0 -8
- package/views/casa/partials/phase_banner_beta.njk +0 -8
- package/views/casa/review/page-block.njk +0 -8
- package/views/casa/review/review.njk +0 -47
package/lib/JourneyContext.js
DELETED
|
@@ -1,552 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Represents the state of a user's journey through the Plan. It contains
|
|
3
|
-
* information about:
|
|
4
|
-
*
|
|
5
|
-
* - Data gathered during the journey
|
|
6
|
-
* - Validation errors on that data
|
|
7
|
-
* - Navigation information about how the user got where they are.
|
|
8
|
-
*/
|
|
9
|
-
const clonedeep = require('fast-copy');
|
|
10
|
-
const { v4: uuidv4, validate: uuidValidate } = require('uuid');
|
|
11
|
-
const { isObjectType, hasProp } = require('./Util.js');
|
|
12
|
-
const { DEFAULT_CONTEXT_ID } = require('./enums.js');
|
|
13
|
-
|
|
14
|
-
const privates = new WeakMap();
|
|
15
|
-
|
|
16
|
-
class JourneyContext {
|
|
17
|
-
/**
|
|
18
|
-
* Constructor.
|
|
19
|
-
*
|
|
20
|
-
* `data` is the "single source of truth" for all data gathered during the
|
|
21
|
-
* user's journey. This is referred to as the "canonical data model".
|
|
22
|
-
* Page-specific "views" of this data are generated at runtime in order to
|
|
23
|
-
* populate/validate specific form fields.
|
|
24
|
-
*
|
|
25
|
-
* `validation` holds the results of form field validation carried out when
|
|
26
|
-
* page forms are POSTed. These results are mapped directly to per-page,
|
|
27
|
-
* per-field.
|
|
28
|
-
*
|
|
29
|
-
* `nav` holds information about the current navigation state. Currently this
|
|
30
|
-
* comprises of the language in which the user is navigating the service.
|
|
31
|
-
*
|
|
32
|
-
* `identity` holds information that helps uniquely identify this context
|
|
33
|
-
* among a group of contexts stored in the session.
|
|
34
|
-
*
|
|
35
|
-
* @param {object} data Entire journey data.
|
|
36
|
-
* @param {object} validation Page errors (indexed by waypoint id).
|
|
37
|
-
* @param {object} nav Navigation context.
|
|
38
|
-
* @param {object} identity Some metadata for identifying this context among others.
|
|
39
|
-
*/
|
|
40
|
-
constructor(data = {}, validation = {}, nav = {}, identity = {}) {
|
|
41
|
-
privates.set(this, {
|
|
42
|
-
data,
|
|
43
|
-
validation,
|
|
44
|
-
nav,
|
|
45
|
-
identity,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Turn this instance into an object that can be stringified.
|
|
51
|
-
*
|
|
52
|
-
* @returns {object} Plain object.
|
|
53
|
-
*/
|
|
54
|
-
toObject() {
|
|
55
|
-
return Object.assign(Object.create(null), {
|
|
56
|
-
data: this.getData(),
|
|
57
|
-
validation: this.getValidationErrors(),
|
|
58
|
-
nav: this.getNavigation(),
|
|
59
|
-
identity: this.getIdentity(),
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Create a new JourneyContext using the plain object.
|
|
65
|
-
*
|
|
66
|
-
* @param {object} obj Object.
|
|
67
|
-
* @returns {JourneyContext} Instance.
|
|
68
|
-
*/
|
|
69
|
-
static fromObject(obj = {}) {
|
|
70
|
-
return new JourneyContext(
|
|
71
|
-
hasProp(obj, 'data') ? obj.data : Object.create(null),
|
|
72
|
-
hasProp(obj, 'validation') ? obj.validation : Object.create(null),
|
|
73
|
-
hasProp(obj, 'nav') ? obj.nav : Object.create(null),
|
|
74
|
-
hasProp(obj, 'identity') ? obj.identity : Object.create(null),
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
get data() {
|
|
79
|
-
return this.getData();
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
get validation() {
|
|
83
|
-
return this.getValidationErrors();
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
get nav() {
|
|
87
|
-
return this.getNavigation();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
get identity() {
|
|
91
|
-
return this.getIdentity();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Return the covnerted data context.
|
|
96
|
-
*
|
|
97
|
-
* This is the "form-facing" view of data that contains the per-field map of
|
|
98
|
-
* data. This is generated at call-time. It follows this structure:
|
|
99
|
-
*
|
|
100
|
-
* {
|
|
101
|
-
* "<waypoint-id>": { "<field-name>": <field-value>, "<field-name>": <field-value>, ... },
|
|
102
|
-
* "<waypoint-id>": { "<field-name>": <field-value>, "<field-name>": <field-value>, ... },
|
|
103
|
-
* ...
|
|
104
|
-
* }
|
|
105
|
-
*
|
|
106
|
-
* @returns {object} Data context
|
|
107
|
-
*/
|
|
108
|
-
getData() {
|
|
109
|
-
return privates.get(this).data;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Get data context for a specific a specific page.
|
|
114
|
-
*
|
|
115
|
-
* By default this will retrieve data by looking up an object with a key
|
|
116
|
-
* matching the page's waypoint ID. However, when passing a `PageMeta`
|
|
117
|
-
* instance, its `fieldReader()` method will be called to transform the
|
|
118
|
-
* internal context data into a format suitable for populating an HTML form.
|
|
119
|
-
*
|
|
120
|
-
* @param {string | PageMeta} page Page waypoint ID, or PageMeta object.
|
|
121
|
-
* @returns {object} Page data.
|
|
122
|
-
* @throws {TypeError} When page is invalid.
|
|
123
|
-
*/
|
|
124
|
-
getDataForPage(page) {
|
|
125
|
-
const priv = privates.get(this);
|
|
126
|
-
|
|
127
|
-
if (typeof page === 'string') {
|
|
128
|
-
return priv.data[page];
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (isObjectType(page)) {
|
|
132
|
-
if (
|
|
133
|
-
Object.prototype.hasOwnProperty.call(page, 'fieldReader')
|
|
134
|
-
&& typeof page.fieldReader === 'function'
|
|
135
|
-
) {
|
|
136
|
-
return page.fieldReader({
|
|
137
|
-
waypointId: page.id,
|
|
138
|
-
contextData: clonedeep(priv.data),
|
|
139
|
-
})
|
|
140
|
-
}
|
|
141
|
-
return priv.data[page.id];
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
throw new TypeError(`Page must be a string or PageMeta object. Got ${typeof page}`)
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Overwrite the data context with a new object.
|
|
149
|
-
*
|
|
150
|
-
* @param {object} data Data that will overwrite all existing data.
|
|
151
|
-
* @returns {JourneyContext} Chain.
|
|
152
|
-
*/
|
|
153
|
-
setData(data) {
|
|
154
|
-
const priv = privates.get(this);
|
|
155
|
-
priv.data = data;
|
|
156
|
-
privates.set(this, priv);
|
|
157
|
-
return this;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Write field form data from a page HTML form, into the `data` model.
|
|
162
|
-
*
|
|
163
|
-
* By default this will store the data as-is, keyed against the page's
|
|
164
|
-
* waypoint ID. However, when passing a `PageMeta` instance, its
|
|
165
|
-
* `fieldWriter()` method will be called to transform the provided formData
|
|
166
|
-
* before storing in `data`
|
|
167
|
-
*
|
|
168
|
-
* @param {string | PageMeta} page Page waypoint ID, or PageMeta object
|
|
169
|
-
* @param {object} webFormData Data to overwrite with
|
|
170
|
-
* @returns {JourneyContext} Chain
|
|
171
|
-
* @throws {TypeError} When page is invalid.
|
|
172
|
-
*/
|
|
173
|
-
setDataForPage(page, webFormData) {
|
|
174
|
-
const priv = privates.get(this);
|
|
175
|
-
|
|
176
|
-
if (typeof page === 'string') {
|
|
177
|
-
priv.data[page] = webFormData;
|
|
178
|
-
} else if (isObjectType(page)) {
|
|
179
|
-
if (
|
|
180
|
-
Object.prototype.hasOwnProperty.call(page, 'fieldWriter')
|
|
181
|
-
&& typeof page.fieldWriter === 'function'
|
|
182
|
-
) {
|
|
183
|
-
priv.data = page.fieldWriter({
|
|
184
|
-
waypointId: page.id,
|
|
185
|
-
formData: webFormData,
|
|
186
|
-
contextData: priv.data, // clone not required as we overwrite anyway
|
|
187
|
-
});
|
|
188
|
-
} else {
|
|
189
|
-
priv.data[page.id] = webFormData;
|
|
190
|
-
}
|
|
191
|
-
} else {
|
|
192
|
-
throw new TypeError(`Page must be a string or PageMeta object. Got ${typeof page}`)
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
privates.set(this, priv);
|
|
196
|
-
return this;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Return validation errors for all pages.
|
|
201
|
-
*
|
|
202
|
-
* @returns {object} All page validation errors.
|
|
203
|
-
*/
|
|
204
|
-
getValidationErrors() {
|
|
205
|
-
return privates.get(this).validation;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Removes any validation state for the given page. Clearing validation state
|
|
210
|
-
* completely will, by default, prevent onward traversal from this page. See
|
|
211
|
-
* the traversal logic in Plan class.
|
|
212
|
-
*
|
|
213
|
-
* @param {string} pageId Page ID.
|
|
214
|
-
* @returns {JourneyContext} Chain.
|
|
215
|
-
*/
|
|
216
|
-
removeValidationStateForPage(pageId) {
|
|
217
|
-
const priv = privates.get(this);
|
|
218
|
-
delete priv.validation[pageId];
|
|
219
|
-
privates.set(this, priv);
|
|
220
|
-
return this;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Clear any validation errors for the given page. This effectively declares
|
|
225
|
-
* that this page has been successfully validated, and so can be traversed. If
|
|
226
|
-
* you want to remove any knowledge of validation success/failure, use
|
|
227
|
-
* `removeValidationStateForPage()` instead.
|
|
228
|
-
*
|
|
229
|
-
* @param {string} pageId Page ID.
|
|
230
|
-
* @returns {JourneyContext} Chain.
|
|
231
|
-
*/
|
|
232
|
-
clearValidationErrorsForPage(pageId) {
|
|
233
|
-
const priv = privates.get(this);
|
|
234
|
-
priv.validation[pageId] = null;
|
|
235
|
-
privates.set(this, priv);
|
|
236
|
-
return this;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Set validation errors for a page.
|
|
241
|
-
*
|
|
242
|
-
* @param {string} pageId Page ID.
|
|
243
|
-
* @param {object} errors Errors index by field name (as generated by Validation.processor).
|
|
244
|
-
* @returns {JourneyContext} Chain.
|
|
245
|
-
* @throws {SyntaxError} When errors are invalid.
|
|
246
|
-
*/
|
|
247
|
-
setValidationErrorsForPage(pageId, errors = {}) {
|
|
248
|
-
const priv = privates.get(this);
|
|
249
|
-
|
|
250
|
-
if (!isObjectType(errors)) {
|
|
251
|
-
throw new SyntaxError(`Errors must be an Object. Recieved ${Object.prototype.toString.call(errors)}`);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
Object.keys(errors).forEach((k) => {
|
|
255
|
-
if (!Array.isArray(errors[k])) {
|
|
256
|
-
throw new SyntaxError('Field errors must be an array');
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
priv.validation[pageId] = errors;
|
|
261
|
-
|
|
262
|
-
privates.set(this, priv);
|
|
263
|
-
return this;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Return the validation errors associated with the page's currently held data
|
|
268
|
-
* context (if any).
|
|
269
|
-
*
|
|
270
|
-
* @param {string} pageId Page ID.
|
|
271
|
-
* @returns {object} An object of errors, indexed by field name.
|
|
272
|
-
*/
|
|
273
|
-
getValidationErrorsForPage(pageId) {
|
|
274
|
-
return privates.get(this).validation[pageId] || Object.create(null);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Determine whether the specified page has any errors in its validation
|
|
279
|
-
* context.
|
|
280
|
-
*
|
|
281
|
-
* @param {string} pageId Page ID.
|
|
282
|
-
* @returns {boolean} Result.
|
|
283
|
-
*/
|
|
284
|
-
hasValidationErrorsForPage(pageId) {
|
|
285
|
-
return Object.keys(this.getValidationErrorsForPage(pageId)).length > 0;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Return navigation state information, in the format:
|
|
290
|
-
* {
|
|
291
|
-
* language: 'en', // language code (ISO 639-1 2-letter code)
|
|
292
|
-
* }
|
|
293
|
-
*
|
|
294
|
-
* @returns {object} Navigation state
|
|
295
|
-
*/
|
|
296
|
-
getNavigation() {
|
|
297
|
-
return privates.get(this).nav;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* Set language of the context.
|
|
302
|
-
*
|
|
303
|
-
* @param {string} language Language to set (ISO 639-1 2-letter code).
|
|
304
|
-
* @returns {JourneyContext} Chain.
|
|
305
|
-
*/
|
|
306
|
-
setNavigationLanguage(language = 'en') {
|
|
307
|
-
const priv = privates.get(this);
|
|
308
|
-
priv.nav.language = language;
|
|
309
|
-
privates.set(this, priv);
|
|
310
|
-
return this;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Convenience function to test if page is valid.
|
|
315
|
-
*
|
|
316
|
-
* @param {string} pageId Page ID.
|
|
317
|
-
* @returns {boolean} True if the page is valid.
|
|
318
|
-
*/
|
|
319
|
-
isPageValid(pageId) {
|
|
320
|
-
return privates.get(this).validation[pageId] === null;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/* ----------------------------------------------- session context handling */
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Construct a new JourneyContext instance frmo another instance.
|
|
327
|
-
*
|
|
328
|
-
* @param {JourneyContext} context Context to copy from
|
|
329
|
-
* @returns {JourneyContext} Constructed JourneyContext instance
|
|
330
|
-
* @throws {TypeError} When context is not a valid type
|
|
331
|
-
*/
|
|
332
|
-
static fromContext(context) {
|
|
333
|
-
if (!(context instanceof JourneyContext)) {
|
|
334
|
-
throw new TypeError('Source context must be a JourneyContext');
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
const newContextObj = context.toObject();
|
|
338
|
-
newContextObj.identity = Object.assign(Object.create(null), { id: uuidv4() });
|
|
339
|
-
return JourneyContext.fromObject(newContextObj);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Get identity information. Returns an object:
|
|
344
|
-
* {
|
|
345
|
-
* id: <string>, // uuid | "default" | default undefined
|
|
346
|
-
* name: <string>, // default undefined
|
|
347
|
-
* tags: <array<string>> // default undefined
|
|
348
|
-
* }
|
|
349
|
-
*
|
|
350
|
-
* @returns {object} Identity object (see above)
|
|
351
|
-
*/
|
|
352
|
-
getIdentity() {
|
|
353
|
-
return privates.get(this).identity;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Convenience method to determine if this is the default context.
|
|
358
|
-
*
|
|
359
|
-
* @returns {boolean} True if this is the "default" journey context
|
|
360
|
-
*/
|
|
361
|
-
isDefault() {
|
|
362
|
-
return this.getIdentity().id === DEFAULT_CONTEXT_ID;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
/**
|
|
366
|
-
* Initialise session with an empty entry for the "default" context.
|
|
367
|
-
*
|
|
368
|
-
* @param {object} session Request session
|
|
369
|
-
* @returns {void}
|
|
370
|
-
*/
|
|
371
|
-
static initContextStore(session) {
|
|
372
|
-
if (!hasProp(session, 'journeyContextList')) {
|
|
373
|
-
/* eslint-disable-next-line no-param-reassign */
|
|
374
|
-
session.journeyContextList = Object.create(null);
|
|
375
|
-
|
|
376
|
-
const defaultContext = new JourneyContext();
|
|
377
|
-
defaultContext.identity.id = DEFAULT_CONTEXT_ID;
|
|
378
|
-
JourneyContext.putContext(session, defaultContext);
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Validate the format of a context ID, i.e. "default" or a uuid
|
|
384
|
-
* eg 00000000-0000-0000-0000-000000000000
|
|
385
|
-
* eg 123e4567-e89b-12d3-a456-426614174000
|
|
386
|
-
*
|
|
387
|
-
* @param {string} id Context ID
|
|
388
|
-
* @returns {string} Original ID if it's valid
|
|
389
|
-
* @throws {TypeError} When id is not a valid type
|
|
390
|
-
* @throws {SyntaxError} When id is not a valid uuid format
|
|
391
|
-
*/
|
|
392
|
-
static validateContextId(id) {
|
|
393
|
-
if (id === DEFAULT_CONTEXT_ID) {
|
|
394
|
-
return DEFAULT_CONTEXT_ID;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
if (typeof id !== 'string') {
|
|
398
|
-
throw new TypeError('Context ID must be a string');
|
|
399
|
-
} else if (!uuidValidate(id)) {
|
|
400
|
-
throw new SyntaxError('Context ID is not in the correct uuid format');
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
return id;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* Lookup context from session using the ID.
|
|
408
|
-
*
|
|
409
|
-
* @param {object} session Request session
|
|
410
|
-
* @param {string} id Context ID
|
|
411
|
-
* @returns {JourneyContext} The discovered JourneyContext instance
|
|
412
|
-
*/
|
|
413
|
-
static getContextById(session, id) {
|
|
414
|
-
if (session && hasProp(session.journeyContextList, id)) {
|
|
415
|
-
return JourneyContext.fromObject(session.journeyContextList[id]);
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
return undefined;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
/**
|
|
422
|
-
* Lookup context from session using the name.
|
|
423
|
-
*
|
|
424
|
-
* @param {object} session Request session
|
|
425
|
-
* @param {string} name Context name
|
|
426
|
-
* @returns {JourneyContext} The discovered JourneyContext instance
|
|
427
|
-
*/
|
|
428
|
-
static getContextByName(session, name) {
|
|
429
|
-
if (session) {
|
|
430
|
-
const context = Object.values(session.journeyContextList).find(
|
|
431
|
-
(c) => (c.identity.name === name),
|
|
432
|
-
);
|
|
433
|
-
if (context) {
|
|
434
|
-
return JourneyContext.fromObject(context);
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
return undefined;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Lookup contexts from session using the tag.
|
|
443
|
-
*
|
|
444
|
-
* @param {object} session Request session
|
|
445
|
-
* @param {string} tag Context tag
|
|
446
|
-
* @returns {Array<JourneyContext>} The discovered JourneyContext instance
|
|
447
|
-
*/
|
|
448
|
-
static getContextsByTag(session, tag) {
|
|
449
|
-
if (session) {
|
|
450
|
-
return Object.values(session.journeyContextList).filter(
|
|
451
|
-
(c) => (c.identity.tags?.includes(tag)),
|
|
452
|
-
).map((c) => (JourneyContext.fromObject(c)));
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
return undefined;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
/**
|
|
459
|
-
* Return all contexts currently stored in the session.
|
|
460
|
-
*
|
|
461
|
-
* @param {object} session Request session
|
|
462
|
-
* @returns {Array} Array of contexts
|
|
463
|
-
*/
|
|
464
|
-
static getContexts(session) {
|
|
465
|
-
if (hasProp(session, 'journeyContextList')) {
|
|
466
|
-
return Object.values(session.journeyContextList).map((contextObj) => (
|
|
467
|
-
JourneyContext.fromObject(contextObj)
|
|
468
|
-
));
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
return [];
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
/**
|
|
475
|
-
* Put context back into the session store.
|
|
476
|
-
*
|
|
477
|
-
* @param {object} session Request session
|
|
478
|
-
* @param {JourneyContext} context Context
|
|
479
|
-
* @returns {void}
|
|
480
|
-
* @throws {TypeError} When isession is not a valid type, or context has no ID
|
|
481
|
-
*/
|
|
482
|
-
static putContext(session, context) {
|
|
483
|
-
if (!isObjectType(session)) {
|
|
484
|
-
throw new TypeError('Session must be an object');
|
|
485
|
-
} else if (!(context instanceof JourneyContext)) {
|
|
486
|
-
throw new TypeError('Context must be a valid JourneyContext');
|
|
487
|
-
} else if (context.identity.id === undefined) {
|
|
488
|
-
throw new TypeError('Context must have an ID before storing in session');
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
// Initialise the session if necessary
|
|
492
|
-
if (!hasProp(session, 'journeyContextList')) {
|
|
493
|
-
JourneyContext.initContextStore(session);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
/* eslint-disable-next-line no-param-reassign */
|
|
497
|
-
session.journeyContextList[context.identity.id] = context.toObject();
|
|
498
|
-
|
|
499
|
-
// TODO: This block of code _might_ be needed if users still want to use
|
|
500
|
-
// the `session.journeyContext` object, which is just a convenient copy of
|
|
501
|
-
// the data in `req.casa.journeyContext` - but it can introduce confusing
|
|
502
|
-
// behaviours if the two ever become misaligned, so would rather not keep it
|
|
503
|
-
|
|
504
|
-
// // Update the "active context" reference in the session, if it is the one
|
|
505
|
-
// // being updated.
|
|
506
|
-
// if (
|
|
507
|
-
// hasProp(session, 'journeyContext')
|
|
508
|
-
// && context.identity.id === session.journeyContext.identity.id
|
|
509
|
-
// ) {
|
|
510
|
-
// session.journeyContext = session.journeyContextList[context.identity.id];
|
|
511
|
-
// }
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
/**
|
|
515
|
-
* Remove a context from the session store.
|
|
516
|
-
*
|
|
517
|
-
* @param {object} session Request session
|
|
518
|
-
* @param {JourneyContext} context Context
|
|
519
|
-
* @returns {void}
|
|
520
|
-
*/
|
|
521
|
-
static removeContext(session, context) {
|
|
522
|
-
if (context instanceof JourneyContext) {
|
|
523
|
-
JourneyContext.removeContextById(session, context.identity.id);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
static removeContextById(session, id) {
|
|
528
|
-
if (session && hasProp(session.journeyContextList, id)) {
|
|
529
|
-
/* eslint-disable-next-line no-param-reassign */
|
|
530
|
-
delete session.journeyContextList[id];
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
static removeContextByName(session, name) {
|
|
535
|
-
JourneyContext.removeContext(
|
|
536
|
-
session,
|
|
537
|
-
JourneyContext.getContextByName(session, name),
|
|
538
|
-
);
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
static removeContextsByTag(session, tag) {
|
|
542
|
-
JourneyContext.getContextsByTag(session, tag).forEach(
|
|
543
|
-
(c) => JourneyContext.removeContext(session, c),
|
|
544
|
-
);
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
static removeContexts(session) {
|
|
548
|
-
JourneyContext.getContexts(session).forEach((c) => JourneyContext.removeContext(session, c));
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
module.exports = JourneyContext;
|