@dwp/govuk-casa 7.0.8 → 7.0.9

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 (100) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/middleware/page/journey-continue.js +5 -0
  3. package/package.json +15 -15
  4. package/dist/assets/css/casa-ie8.css +0 -1
  5. package/dist/assets/css/casa.css +0 -1
  6. package/dist/casa.d.ts +0 -11
  7. package/dist/casa.js +0 -46
  8. package/dist/lib/CasaTemplateLoader.d.ts +0 -29
  9. package/dist/lib/CasaTemplateLoader.js +0 -74
  10. package/dist/lib/JourneyContext.d.ts +0 -297
  11. package/dist/lib/JourneyContext.js +0 -581
  12. package/dist/lib/MutableRouter.d.ts +0 -155
  13. package/dist/lib/MutableRouter.js +0 -277
  14. package/dist/lib/Plan.d.ts +0 -154
  15. package/dist/lib/Plan.js +0 -442
  16. package/dist/lib/ValidationError.d.ts +0 -74
  17. package/dist/lib/ValidationError.js +0 -159
  18. package/dist/lib/ValidatorFactory.d.ts +0 -83
  19. package/dist/lib/ValidatorFactory.js +0 -106
  20. package/dist/lib/configuration-ingestor.d.ts +0 -262
  21. package/dist/lib/configuration-ingestor.js +0 -490
  22. package/dist/lib/configure.d.ts +0 -90
  23. package/dist/lib/configure.js +0 -192
  24. package/dist/lib/dirname.cjs +0 -1
  25. package/dist/lib/dirname.d.cts +0 -2
  26. package/dist/lib/end-session.d.ts +0 -13
  27. package/dist/lib/end-session.js +0 -43
  28. package/dist/lib/field.d.ts +0 -77
  29. package/dist/lib/field.js +0 -255
  30. package/dist/lib/index.d.ts +0 -14
  31. package/dist/lib/index.js +0 -54
  32. package/dist/lib/logger.d.ts +0 -9
  33. package/dist/lib/logger.js +0 -18
  34. package/dist/lib/nunjucks-filters.d.ts +0 -26
  35. package/dist/lib/nunjucks-filters.js +0 -90
  36. package/dist/lib/nunjucks.d.ts +0 -23
  37. package/dist/lib/nunjucks.js +0 -49
  38. package/dist/lib/utils.d.ts +0 -48
  39. package/dist/lib/utils.js +0 -111
  40. package/dist/lib/validators/dateObject.d.ts +0 -4
  41. package/dist/lib/validators/dateObject.js +0 -135
  42. package/dist/lib/validators/email.d.ts +0 -4
  43. package/dist/lib/validators/email.js +0 -46
  44. package/dist/lib/validators/inArray.d.ts +0 -4
  45. package/dist/lib/validators/inArray.js +0 -60
  46. package/dist/lib/validators/index.d.ts +0 -21
  47. package/dist/lib/validators/index.js +0 -47
  48. package/dist/lib/validators/nino.d.ts +0 -4
  49. package/dist/lib/validators/nino.js +0 -46
  50. package/dist/lib/validators/postalAddressObject.d.ts +0 -4
  51. package/dist/lib/validators/postalAddressObject.js +0 -123
  52. package/dist/lib/validators/regex.d.ts +0 -4
  53. package/dist/lib/validators/regex.js +0 -40
  54. package/dist/lib/validators/required.d.ts +0 -4
  55. package/dist/lib/validators/required.js +0 -56
  56. package/dist/lib/validators/strlen.d.ts +0 -4
  57. package/dist/lib/validators/strlen.js +0 -51
  58. package/dist/lib/validators/wordCount.d.ts +0 -5
  59. package/dist/lib/validators/wordCount.js +0 -54
  60. package/dist/lib/waypoint-url.d.ts +0 -23
  61. package/dist/lib/waypoint-url.js +0 -52
  62. package/dist/middleware/body-parser.d.ts +0 -1
  63. package/dist/middleware/body-parser.js +0 -24
  64. package/dist/middleware/csrf.d.ts +0 -1
  65. package/dist/middleware/csrf.js +0 -31
  66. package/dist/middleware/data.d.ts +0 -5
  67. package/dist/middleware/data.js +0 -53
  68. package/dist/middleware/dirname.cjs +0 -1
  69. package/dist/middleware/dirname.d.cts +0 -2
  70. package/dist/middleware/gather-fields.d.ts +0 -6
  71. package/dist/middleware/gather-fields.js +0 -48
  72. package/dist/middleware/i18n.d.ts +0 -4
  73. package/dist/middleware/i18n.js +0 -88
  74. package/dist/middleware/post.d.ts +0 -3
  75. package/dist/middleware/post.js +0 -57
  76. package/dist/middleware/pre.d.ts +0 -3
  77. package/dist/middleware/pre.js +0 -51
  78. package/dist/middleware/progress-journey.d.ts +0 -6
  79. package/dist/middleware/progress-journey.js +0 -80
  80. package/dist/middleware/sanitise-fields.d.ts +0 -5
  81. package/dist/middleware/sanitise-fields.js +0 -53
  82. package/dist/middleware/session.d.ts +0 -11
  83. package/dist/middleware/session.js +0 -121
  84. package/dist/middleware/skip-waypoint.d.ts +0 -5
  85. package/dist/middleware/skip-waypoint.js +0 -43
  86. package/dist/middleware/steer-journey.d.ts +0 -7
  87. package/dist/middleware/steer-journey.js +0 -62
  88. package/dist/middleware/validate-fields.d.ts +0 -7
  89. package/dist/middleware/validate-fields.js +0 -67
  90. package/dist/mjs/esm-wrapper.js +0 -11
  91. package/dist/mjs/package.json +0 -3
  92. package/dist/package.json +0 -3
  93. package/dist/routes/ancillary.d.ts +0 -11
  94. package/dist/routes/ancillary.js +0 -27
  95. package/dist/routes/dirname.cjs +0 -1
  96. package/dist/routes/dirname.d.cts +0 -2
  97. package/dist/routes/journey.d.ts +0 -8
  98. package/dist/routes/journey.js +0 -127
  99. package/dist/routes/static.d.ts +0 -26
  100. package/dist/routes/static.js +0 -68
package/dist/lib/Plan.js DELETED
@@ -1,442 +0,0 @@
1
- "use strict";
2
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
- if (kind === "m") throw new TypeError("Private method is not writable");
4
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
- };
8
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
- };
13
- var __importDefault = (this && this.__importDefault) || function (mod) {
14
- return (mod && mod.__esModule) ? mod : { "default": mod };
15
- };
16
- var _Plan_skippableWaypoints;
17
- Object.defineProperty(exports, "__esModule", { value: true });
18
- const graphlib_1 = require("graphlib");
19
- const JourneyContext_js_1 = __importDefault(require("./JourneyContext.js"));
20
- const logger_js_1 = __importDefault(require("./logger.js"));
21
- const log = (0, logger_js_1.default)('class:plan');
22
- /**
23
- * Will check if the source waypoint has specifically passed validation, i.e
24
- * there is a "null" validation entry for the route source.
25
- *
26
- * @param {object} r Route meta.
27
- * @param {JourneyContext} context Journey Context.
28
- * @returns {boolean} Condition result.
29
- */
30
- function defaultNextFollow(r, context) {
31
- const { validation: v = {} } = context.toObject();
32
- return Object.prototype.hasOwnProperty.call(v, r.source) && v[r.source] === null;
33
- }
34
- /**
35
- * Will check if the target waypoint (the one we're moving back to) has
36
- * specifically passed validation.
37
- *
38
- * @param {object} r Route meta.
39
- * @param {JourneyContext} context Journey context.
40
- * @returns {boolean} Condition result.
41
- */
42
- function defaultPrevFollow(r, context) {
43
- const { validation: v = {} } = context.toObject();
44
- return Object.prototype.hasOwnProperty.call(v, r.target) && v[r.target] === null;
45
- }
46
- function validateWaypointId(val) {
47
- if (typeof val !== 'string') {
48
- throw new TypeError(`Expected waypoint id to be a string, got ${typeof val}`);
49
- }
50
- if (val.substr(0, 6) === 'url://' && !val.endsWith('/')) {
51
- throw new SyntaxError('url:// waypoints must include a trailing /');
52
- }
53
- }
54
- function validateRouteName(val) {
55
- if (typeof val !== 'string') {
56
- throw new TypeError(`Expected route name to be a string, got ${typeof val}`);
57
- }
58
- else if (!['next', 'prev'].includes(val)) {
59
- throw new ReferenceError(`Expected route name to be one of next or prev. Got ${val}`);
60
- }
61
- }
62
- function validateRouteCondition(val) {
63
- if (!(val instanceof Function)) {
64
- throw new TypeError(`Expected route condition to be a function, got ${typeof val}`);
65
- }
66
- }
67
- /**
68
- * Creates a user friendly route structure from a given graph edge which will
69
- * be used in userland. This is the object that will be passed into follow
70
- * functions too as the "route" parameter.
71
- *
72
- * @param {object} dgraph Directed graph instance.
73
- * @param {object} edge Graph edge object.
74
- * @returns {object} Route.
75
- */
76
- const makeRouteObject = (dgraph, edge) => {
77
- const label = dgraph.edge(edge) || {};
78
- return {
79
- source: edge.v,
80
- target: edge.w,
81
- name: edge.name,
82
- // label: {},
83
- label,
84
- };
85
- };
86
- /**
87
- * Exit nodes begin with a protocol format, such as `url://`, `http://`, etc
88
- */
89
- const reExitNodeProtocol = /^[a-z]+:\/\//i;
90
- const priv = new WeakMap();
91
- class Plan {
92
- /**
93
- * Create a Plan.
94
- *
95
- * @param {object} opts Options
96
- * @param {boolean} [opts.validateBeforeRouteCondition=true] Check page validity before conditions
97
- * @param {Function|string} [opts.arbiter=undefined] Arbitration mechanism
98
- */
99
- constructor(opts = {}) {
100
- /**
101
- * @type {string[]} These waypoints can be skipped
102
- */
103
- _Plan_skippableWaypoints.set(this, void 0);
104
- // This is our directed, multigraph representation
105
- const dgraph = new graphlib_1.Graph({
106
- directed: true,
107
- multigraph: true,
108
- compound: false,
109
- });
110
- // Gather options
111
- const options = Object.assign(Object.create(null), {
112
- // When true, the validation state of the source node must be `null` (i.e.
113
- // no validation errors) before any custom route conditions are evaluated.
114
- validateBeforeRouteCondition: true,
115
- // Traversal arbitration
116
- arbiter: undefined,
117
- }, opts);
118
- Object.freeze(options);
119
- priv.set(this, {
120
- dgraph,
121
- follows: {
122
- next: {},
123
- prev: {},
124
- },
125
- options,
126
- });
127
- __classPrivateFieldSet(this, _Plan_skippableWaypoints, [], "f");
128
- }
129
- /**
130
- * Waypoints using the url:// protocol are known as "exit nodes" as they
131
- * indicate an exit point to another Plan.
132
- *
133
- * @param {string} name Waypoint name
134
- * @returns {boolean} True if the waypoint is a url:// type
135
- */
136
- static isExitNode(name) {
137
- return reExitNodeProtocol.test(name);
138
- }
139
- getOptions() {
140
- return priv.get(this).options;
141
- }
142
- /**
143
- * Retrieve the list of skippable waypoints.
144
- *
145
- * @returns {string[]} List of skippable waypoints
146
- */
147
- getSkippables() {
148
- return __classPrivateFieldGet(this, _Plan_skippableWaypoints, "f");
149
- }
150
- /**
151
- * Add one or more skippable waypoints.
152
- *
153
- * @param {...string} waypoints Waypoints
154
- * @returns {Plan}{ Chain}
155
- */
156
- addSkippables(...waypoints) {
157
- __classPrivateFieldSet(this, _Plan_skippableWaypoints, [...__classPrivateFieldGet(this, _Plan_skippableWaypoints, "f"), ...waypoints], "f");
158
- return this;
159
- }
160
- /**
161
- * Check if the user can skip the named waypoint.
162
- *
163
- * @param {string} waypoint Waypoint
164
- * @returns {boolean} True if waypoint can be skipped
165
- */
166
- isSkippable(waypoint) {
167
- return __classPrivateFieldGet(this, _Plan_skippableWaypoints, "f").indexOf(waypoint) > -1;
168
- }
169
- getWaypoints() {
170
- return priv.get(this).dgraph.nodes();
171
- }
172
- containsWaypoint(waypoint) {
173
- return this.getWaypoints().includes(waypoint);
174
- }
175
- getRoutes() {
176
- const self = priv.get(this);
177
- return self.dgraph.edges().map((edge) => makeRouteObject(self.dgraph, edge));
178
- }
179
- getRouteCondition(src, tgt, name) {
180
- return priv.get(this).follows[name][`${src}/${tgt}`];
181
- }
182
- /**
183
- * Return all outward routes (out-edges) from the given waypoint, to the
184
- * optional target waypoint.
185
- *
186
- * @param {string} src Source waypoint.
187
- * @param {string} tgt Target waypoint (optional).
188
- * @returns {Array<object>} Route objects found.
189
- */
190
- getOutwardRoutes(src, tgt = null) {
191
- const self = priv.get(this);
192
- return self.dgraph.outEdges(src, tgt).map((e) => makeRouteObject(self.dgraph, e));
193
- }
194
- /**
195
- * Return all outward routes (out-edges) from the given waypoint, to the
196
- * optional target waypoint, matching the "prev" name.
197
- *
198
- * @param {string} src Source waypoint.
199
- * @param {string} tgt Target waypoint (optional).
200
- * @returns {Array<object>} Route objects found.
201
- */
202
- getPrevOutwardRoutes(src, tgt = null) {
203
- return this.getOutwardRoutes(src, tgt).filter((r) => r.name === 'prev');
204
- }
205
- addSequence(...waypoints) {
206
- // Setup simple double routes (next/prev) between all waypoints in this list
207
- for (let i = 0, l = waypoints.length - 1; i < l; i += 1) {
208
- this.setRoute(waypoints[i], waypoints[i + 1]);
209
- }
210
- }
211
- setNextRoute(src, tgt, follow) {
212
- return this.setNamedRoute(src, tgt, 'next', follow);
213
- }
214
- setPrevRoute(src, tgt, follow) {
215
- return this.setNamedRoute(src, tgt, 'prev', follow);
216
- }
217
- /**
218
- * Adds both a "next" and "prev" route between the two waypoints.
219
- *
220
- * By default, the "prev" route will use the same "follow" test as the "next"
221
- * route. This makes sense in that in order to get the target, the test must
222
- * have been true, and so to reverse the direction we also need that same test
223
- * to be true.
224
- *
225
- * However, if the condition function uses the `source`/`target`
226
- * of the route in some way, then we must reverse these before passing to the
227
- * condition on the "prev" route because `source` in the condition will almost
228
- * certainly be referring to the source of the "next" route.
229
- *
230
- * If `tgt` is an egress node, do not create a `prev` route for it, because
231
- * there's no way back from that point to this Plan.
232
- *
233
- * @param {string} src Source waypoint.
234
- * @param {string} tgt Target waypoint.
235
- * @param {Function} followNext Follow test function.
236
- * @param {Function} followPrev Follow test function.
237
- * @returns {Plan} Self.
238
- */
239
- setRoute(src, tgt, followNext = undefined, followPrev = undefined) {
240
- this.setNamedRoute(src, tgt, 'next', followNext);
241
- let followPrevious = followPrev;
242
- if (followPrevious === undefined) {
243
- followPrevious = followNext === undefined ? undefined : (r, c) => {
244
- const invertedRoute = Object.assign(Object.assign({}, r), { source: r.target, target: r.source });
245
- return followNext(invertedRoute, c);
246
- };
247
- }
248
- this.setNamedRoute(tgt, src, 'prev', followPrevious);
249
- return this;
250
- }
251
- /**
252
- * Create a named route between two waypoints, and give that route a function
253
- * that determine whether it should be followed during traversal operations.
254
- * Note that the source waypoint must be in a successful validation state
255
- * to be considered for traversal, regardless of what the custom function
256
- * determines.
257
- *
258
- * You may also define routes that take the user to any generic URL within the
259
- * same domain by using the `url://` protocol. These are considered
260
- * "exit nodes".
261
- *
262
- * setNamedRoute("my-waypoint", "url:///some/absolute/url");
263
- *
264
- * @param {string} src Source waypoint.
265
- * @param {string} tgt Target waypoint.
266
- * @param {string} name Name of the route (must be unique for this waypoint pairing).
267
- * @param {Function} follow Test function to determine if route can be followed.
268
- * @returns {Plan} Chain
269
- * @throws {Error} If attempting to create a "next" route from an exit node
270
- */
271
- setNamedRoute(src, tgt, name, follow) {
272
- const self = priv.get(this);
273
- // Validate
274
- validateWaypointId(src);
275
- validateWaypointId(tgt);
276
- validateRouteName(name);
277
- if (follow !== undefined) {
278
- validateRouteCondition(follow);
279
- }
280
- // Get routing function name to label edge
281
- const conditionName = follow && follow.name;
282
- // Warn if we're overwriting an existing edge on the same name
283
- if (self.dgraph.hasEdge(src, tgt, name)) {
284
- log.warn('Setting a route that already exists (%s, %s, %s). Will be overridden', src, tgt, name);
285
- }
286
- self.dgraph.setEdge(src, tgt, { conditionName }, name);
287
- // Determine which follow function to use
288
- let followFunc;
289
- if (follow) {
290
- if (!self.options.validateBeforeRouteCondition) {
291
- followFunc = follow;
292
- }
293
- else if (name === 'next') {
294
- // Retain the original function name of route condition
295
- followFunc = {
296
- [follow.name]: (r, c) => (defaultNextFollow(r, c) && follow(r, c)),
297
- }[follow.name];
298
- }
299
- else {
300
- // Retain the original function name of route condition
301
- followFunc = {
302
- [follow.name]: (r, c) => (defaultPrevFollow(r, c) && follow(r, c)),
303
- }[follow.name];
304
- }
305
- }
306
- else if (name === 'next') {
307
- followFunc = defaultNextFollow;
308
- }
309
- else {
310
- followFunc = defaultPrevFollow;
311
- }
312
- self.follows[name][`${src}/${tgt}`] = followFunc;
313
- return this;
314
- }
315
- /**
316
- * This is a convenience method for traversing all "next" routes, and returning
317
- * the IDs of all waypoints visited along the way.
318
- *
319
- * @param {JourneyContext} context Journey Context.
320
- * @param {object} options Options.
321
- * @returns {Array<string>} List of traversed waypoints.
322
- */
323
- traverse(context, options = {}) {
324
- return this.traverseNextRoutes(context, options).map((e) => e.source);
325
- }
326
- traverseNextRoutes(context, options = {}) {
327
- return this.traverseRoutes(context, Object.assign(Object.assign({}, options), { routeName: 'next' }));
328
- }
329
- traversePrevRoutes(context, options = {}) {
330
- return this.traverseRoutes(context, Object.assign(Object.assign({}, options), { routeName: 'prev' }));
331
- }
332
- /**
333
- * Traverse through the plan from a particular starting waypoint. This is a
334
- * non-exhaustive Graph Exploration.
335
- *
336
- * The last route in the list will contain the source of the last waypoint that
337
- * can be reached, i.e. The waypoint that has no further satisfiable out-edges.
338
- *
339
- * If a cyclical set of routes are encountered, traversal will stop after
340
- * reaching the first repeated waypoint.
341
- *
342
- * Options:
343
- * string startWaypoint = Waypoint from which to start traversal
344
- * string routeName = Follow routes matching this name (next | prev)
345
- * Map history = Used to detect loops in traversal (internal use)
346
- * function stopCondition = Condition that, if true, will stop traversal (useful for performance)
347
- * function|string arbiter = If mutliple target routes found, this decides which to use (if any)
348
- *
349
- * @param {JourneyContext} context Journey context
350
- * @param {object} options Options
351
- * @returns {Array<object>} Routes that were traversed
352
- * @throws {TypeError} When context is not a JourneyContext
353
- */
354
- traverseRoutes(context, options = {}) {
355
- if (!(context instanceof JourneyContext_js_1.default)) {
356
- throw new TypeError(`Expected context to be an instance of JourneyContext, got ${typeof context}`);
357
- }
358
- const self = priv.get(this);
359
- const { startWaypoint = this.getWaypoints()[0], stopCondition = () => (false), arbiter = self.options.arbiter, routeName, } = options;
360
- if (!self.dgraph.hasNode(startWaypoint)) {
361
- throw new ReferenceError(`Plan does not contain waypoint '${startWaypoint}'`);
362
- }
363
- if (routeName === undefined) {
364
- throw new ReferenceError('Route name must be provided');
365
- }
366
- const history = new Map();
367
- const traverse = (startWP) => {
368
- let target = self.dgraph.outEdges(startWP).filter((e) => {
369
- if (e.name !== routeName) {
370
- return false;
371
- }
372
- const route = makeRouteObject(self.dgraph, e);
373
- try {
374
- return self.follows[routeName][`${e.v}/${e.w}`](route, context);
375
- }
376
- catch (ex) {
377
- log.warn('Route follow function threw an exception, "%s" (%s)', ex.message, `${e.v}/${e.w}`);
378
- return false;
379
- }
380
- });
381
- // When there's more than one candidate route to take, we need help to choose
382
- if (target.length > 1) {
383
- const satisifed = target.map((t) => `${t.v} -> ${t.w}`);
384
- log.debug(`Multiple routes were satisfied for "${routeName}" from "${startWP}" (${satisifed.join(' / ')}). Deciding how to resolve ...`);
385
- if (arbiter === 'auto') {
386
- log.debug('Using automatic arbitration process');
387
- const targetNames = target.map(({ w }) => w);
388
- const forwardTraversal = this.traverseNextRoutes(context, {
389
- stopCondition: ({ source }) => targetNames.includes(source),
390
- });
391
- const resolved = forwardTraversal.pop();
392
- target = target.filter((t) => t.w === resolved.source);
393
- }
394
- else if (arbiter instanceof Function) {
395
- log.debug('Using custom arbitration process');
396
- target = arbiter(target, Object.assign({ context }, options));
397
- }
398
- else {
399
- log.warn('Unable to arbitrate');
400
- target = [];
401
- }
402
- }
403
- if (target.length === 1) {
404
- const route = makeRouteObject(self.dgraph, target[0]);
405
- const routeHash = `${route.name}/${route.source}/${route.target}`;
406
- if (stopCondition(route)) {
407
- return [route];
408
- }
409
- if (!history.has(routeHash)) {
410
- history.set(routeHash, null);
411
- const traversed = traverse(target[0].w);
412
- const totalTrav = traversed.length;
413
- const results = new Array(totalTrav + 1);
414
- results[0] = route;
415
- for (let i = 0; i < totalTrav; i++) {
416
- results[i + 1] = traversed[i];
417
- }
418
- return results;
419
- }
420
- log.debug('Encountered loop (%s). Stopping traversal.', `${route.source} -> ${route.target}`);
421
- }
422
- return [makeRouteObject(self.dgraph, {
423
- v: startWP,
424
- w: null,
425
- name: routeName,
426
- label: {},
427
- })];
428
- };
429
- return traverse(startWaypoint);
430
- }
431
- /**
432
- * Get raw graph data structure. This can be used with other libraries to
433
- * generate graph visualisations, for example.
434
- *
435
- * @returns {Graph} Graph data structure.
436
- */
437
- getGraphStructure() {
438
- return priv.get(this).dgraph;
439
- }
440
- }
441
- exports.default = Plan;
442
- _Plan_skippableWaypoints = new WeakMap();
@@ -1,74 +0,0 @@
1
- /**
2
- * @typedef {import('./ValidatorFactory').ValidateContext} ValidateContext
3
- */
4
- export default class ValidationError {
5
- /**
6
- * Make a ValidationError instance from a primitive object (or a function that
7
- * returns a primitive object) that is specific to the given journey context.
8
- *
9
- * The returned `error` (or the function that returns the equivalent) must
10
- * match the structure required by the ValidationError constructor.
11
- *
12
- * `errorMsg` can be one of these formats:
13
- * String => 'common:errors.my-error-message'
14
- * Object => (see constructor argument for structure of this object)
15
- * Function => Function returns object suitable for constructor (see example below)
16
- * Error => A JavaScript error. It's `message` will be used as the error.
17
- *
18
- * `dataContext` is an object containing the same data passed to all validator
19
- * functions, and contains:
20
- * waypointId => The current waypoint being requested
21
- * fieldName => Name of the field being validated
22
- * journeyContext => The full JourneyContext of the current request.
23
- *
24
- * Example function signature that can be used for `errorMsg`:
25
- * ({ waypointId, fieldName, journeyContext }) => ({
26
- * summary: 'my-waypoint:some.key.to.say.hello',
27
- * variables: {
28
- * name: journeyContext.getDataForPage(waypointId).name,
29
- * }
30
- * });
31
- *
32
- * @param {object} args See args above
33
- * @param {any} args.errorMsg Error message to seed the ValidationError
34
- * @param {object} args.dataContext Validation context
35
- * @returns {object} Primitive error matching structure above
36
- * @throws {TypeError} If errorMsg is not in a valid type
37
- */
38
- static make({ errorMsg, dataContext }: {
39
- errorMsg: any;
40
- dataContext: object;
41
- }): object;
42
- /**
43
- * `error` may be a simple string, in which case that string reppresents the
44
- * error mesaage (equivalent to `error.summary` in the structure below).
45
- *
46
- * `error`, when passed as an object, must match this structure:
47
- *
48
- * {
49
- * summary: "", // required
50
- * inline: "", // optional, may be deprecated in future
51
- * focusSuffix: "", // optional
52
- * fieldKeySuffix: "", // optional
53
- * variables: { // optional
54
- * myVariable: 'a value'
55
- * }
56
- * }
57
- *
58
- * @param {object|string} errorParam See object structure above
59
- */
60
- constructor(errorParam?: object | string);
61
- /**
62
- * Modifies the error to reflect the given context.
63
- *
64
- * @param {ValidateContext} context See structure above
65
- * @returns {ValidationError} Chain
66
- */
67
- withContext(context: ValidateContext): ValidationError;
68
- variables: any;
69
- field: string | undefined;
70
- fieldHref: string | undefined;
71
- focusSuffix: any;
72
- validator: any;
73
- }
74
- export type ValidateContext = import('./ValidatorFactory').ValidateContext;
@@ -1,159 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const lodash_1 = __importDefault(require("lodash"));
7
- const { isPlainObject } = lodash_1.default; // CommonJS
8
- const params = new WeakMap();
9
- /**
10
- * @typedef {import('./ValidatorFactory').ValidateContext} ValidateContext
11
- */
12
- class ValidationError {
13
- /**
14
- * Make a ValidationError instance from a primitive object (or a function that
15
- * returns a primitive object) that is specific to the given journey context.
16
- *
17
- * The returned `error` (or the function that returns the equivalent) must
18
- * match the structure required by the ValidationError constructor.
19
- *
20
- * `errorMsg` can be one of these formats:
21
- * String => 'common:errors.my-error-message'
22
- * Object => (see constructor argument for structure of this object)
23
- * Function => Function returns object suitable for constructor (see example below)
24
- * Error => A JavaScript error. It's `message` will be used as the error.
25
- *
26
- * `dataContext` is an object containing the same data passed to all validator
27
- * functions, and contains:
28
- * waypointId => The current waypoint being requested
29
- * fieldName => Name of the field being validated
30
- * journeyContext => The full JourneyContext of the current request.
31
- *
32
- * Example function signature that can be used for `errorMsg`:
33
- * ({ waypointId, fieldName, journeyContext }) => ({
34
- * summary: 'my-waypoint:some.key.to.say.hello',
35
- * variables: {
36
- * name: journeyContext.getDataForPage(waypointId).name,
37
- * }
38
- * });
39
- *
40
- * @param {object} args See args above
41
- * @param {any} args.errorMsg Error message to seed the ValidationError
42
- * @param {object} args.dataContext Validation context
43
- * @returns {object} Primitive error matching structure above
44
- * @throws {TypeError} If errorMsg is not in a valid type
45
- */
46
- static make({ errorMsg, dataContext = {} }) {
47
- // Convert strings to the most basic object primitive
48
- if (typeof errorMsg === 'string') {
49
- return new ValidationError({
50
- summary: errorMsg,
51
- inline: errorMsg,
52
- focusSuffix: [],
53
- });
54
- }
55
- // No contextual changes applicable; return ValidationErorr made from the
56
- // original object
57
- if (isPlainObject(errorMsg)) {
58
- return new ValidationError(errorMsg);
59
- }
60
- // Use the user-defined function to generate an error primitive for the
61
- // given context
62
- if (typeof errorMsg === 'function') {
63
- return new ValidationError(errorMsg.call(null, Object.assign({}, dataContext)));
64
- }
65
- // Core Error
66
- if (errorMsg instanceof Error) {
67
- return new ValidationError({
68
- summary: errorMsg.message,
69
- inline: errorMsg.message,
70
- focusSuffix: errorMsg.focusSuffix || [],
71
- });
72
- }
73
- // Unsupported
74
- throw new TypeError('errorMsg must be a string, Error, primitive object or function that generates a primitive object');
75
- }
76
- /**
77
- * `error` may be a simple string, in which case that string reppresents the
78
- * error mesaage (equivalent to `error.summary` in the structure below).
79
- *
80
- * `error`, when passed as an object, must match this structure:
81
- *
82
- * {
83
- * summary: "", // required
84
- * inline: "", // optional, may be deprecated in future
85
- * focusSuffix: "", // optional
86
- * fieldKeySuffix: "", // optional
87
- * variables: { // optional
88
- * myVariable: 'a value'
89
- * }
90
- * }
91
- *
92
- * @param {object|string} errorParam See object structure above
93
- */
94
- constructor(errorParam = {}) {
95
- if (!isPlainObject(errorParam) && typeof errorParam !== 'string') {
96
- throw new TypeError('Constructor requires a string or object');
97
- }
98
- const error = typeof errorParam === 'string' ? { summary: errorParam } : errorParam;
99
- // Store parameters for later use in applying contexts
100
- const originals = {
101
- summary: error.summary,
102
- // may be deprecated; summary and inline should always match
103
- inline: error.inline || error.summary,
104
- focusSuffix: error.focusSuffix || [],
105
- fieldKeySuffix: error.fieldKeySuffix || undefined,
106
- variables: error.variables || {},
107
- message: error.summary,
108
- field: error.field || undefined,
109
- fieldHref: error.fieldHref || undefined,
110
- validator: error.validator || undefined,
111
- };
112
- params.set(this, originals);
113
- // Duplicate parameters to make them available in public scope. These are
114
- // the values that will be readable, and reflect any context that may have
115
- // been applied
116
- Object.keys(originals).forEach((o) => {
117
- Object.defineProperty(this, o, {
118
- value: originals[o],
119
- enumerable: true,
120
- writable: true,
121
- });
122
- });
123
- }
124
- /**
125
- * Modifies the error to reflect the given context.
126
- *
127
- * @param {ValidateContext} context See structure above
128
- * @returns {ValidationError} Chain
129
- */
130
- withContext(context) {
131
- // Get original constructor parameters
132
- const originals = params.get(this);
133
- // Expand variables
134
- if (typeof originals.variables === 'function') {
135
- this.variables = originals.variables.call(this, context);
136
- }
137
- // Set field name
138
- if (context.fieldName) {
139
- let focusSuffix;
140
- let fieldHref = `#f-${context.fieldName}`;
141
- if (originals.fieldKeySuffix) {
142
- fieldHref += originals.fieldKeySuffix;
143
- }
144
- else if (originals.focusSuffix && originals.focusSuffix.length) {
145
- focusSuffix = Array.isArray(originals.focusSuffix)
146
- ? originals.focusSuffix
147
- : [originals.focusSuffix];
148
- fieldHref += focusSuffix[0];
149
- }
150
- this.field = context.fieldName + (originals.fieldKeySuffix || '');
151
- this.fieldHref = fieldHref;
152
- this.focusSuffix = focusSuffix || [];
153
- }
154
- // Set validator name
155
- this.validator = context.validator || undefined;
156
- return this;
157
- }
158
- }
159
- exports.default = ValidationError;