@dwp/govuk-casa 8.0.0-alpha1 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +1 -1
  3. package/dist/assets/css/casa-ie8.css +1 -1
  4. package/dist/assets/css/casa.css +1 -1
  5. package/dist/casa.d.ts +2 -1
  6. package/dist/casa.js +3 -1
  7. package/dist/lib/CasaTemplateLoader.d.ts +11 -3
  8. package/dist/lib/CasaTemplateLoader.js +38 -2
  9. package/dist/lib/JourneyContext.d.ts +51 -8
  10. package/dist/lib/JourneyContext.js +73 -147
  11. package/dist/lib/MutableRouter.d.ts +19 -19
  12. package/dist/lib/MutableRouter.js +30 -23
  13. package/dist/lib/Plan.d.ts +41 -6
  14. package/dist/lib/Plan.js +84 -17
  15. package/dist/lib/ValidationError.d.ts +6 -2
  16. package/dist/lib/ValidationError.js +7 -0
  17. package/dist/lib/ValidatorFactory.d.ts +72 -13
  18. package/dist/lib/ValidatorFactory.js +33 -14
  19. package/dist/lib/configuration-ingestor.d.ts +262 -0
  20. package/dist/lib/configuration-ingestor.js +464 -0
  21. package/dist/lib/configure.d.ts +39 -154
  22. package/dist/lib/configure.js +35 -59
  23. package/dist/lib/dirname.cjs +1 -1
  24. package/dist/lib/dirname.d.cts +2 -0
  25. package/dist/lib/end-session.d.ts +4 -3
  26. package/dist/lib/end-session.js +30 -8
  27. package/dist/lib/field.d.ts +53 -55
  28. package/dist/lib/field.js +96 -54
  29. package/dist/lib/index.d.ts +14 -0
  30. package/dist/lib/index.js +54 -0
  31. package/dist/lib/logger.d.ts +2 -1
  32. package/dist/lib/logger.js +3 -4
  33. package/dist/lib/nunjucks-filters.d.ts +11 -11
  34. package/dist/lib/nunjucks-filters.js +22 -36
  35. package/dist/lib/nunjucks.d.ts +7 -6
  36. package/dist/lib/nunjucks.js +6 -6
  37. package/dist/lib/utils.d.ts +26 -0
  38. package/dist/lib/utils.js +70 -1
  39. package/dist/lib/validators/dateObject.js +1 -1
  40. package/dist/lib/validators/email.js +1 -1
  41. package/dist/lib/validators/inArray.js +1 -1
  42. package/dist/lib/validators/index.js +0 -22
  43. package/dist/lib/validators/postalAddressObject.js +7 -3
  44. package/dist/lib/validators/required.js +1 -1
  45. package/dist/lib/waypoint-url.d.ts +13 -7
  46. package/dist/lib/waypoint-url.js +13 -7
  47. package/dist/middleware/body-parser.d.ts +2 -1
  48. package/dist/middleware/body-parser.js +20 -11
  49. package/dist/middleware/csrf.d.ts +1 -1
  50. package/dist/middleware/csrf.js +2 -2
  51. package/dist/middleware/data.d.ts +1 -2
  52. package/dist/middleware/data.js +19 -15
  53. package/dist/middleware/dirname.cjs +1 -1
  54. package/dist/middleware/dirname.d.cts +2 -0
  55. package/dist/middleware/gather-fields.d.ts +3 -2
  56. package/dist/middleware/gather-fields.js +14 -7
  57. package/dist/middleware/i18n.d.ts +1 -1
  58. package/dist/middleware/i18n.js +16 -11
  59. package/dist/middleware/post.d.ts +3 -1
  60. package/dist/middleware/post.js +24 -9
  61. package/dist/middleware/pre.js +15 -2
  62. package/dist/middleware/progress-journey.js +15 -17
  63. package/dist/middleware/sanitise-fields.js +15 -10
  64. package/dist/middleware/session.d.ts +2 -1
  65. package/dist/middleware/session.js +65 -52
  66. package/dist/middleware/skip-waypoint.js +10 -7
  67. package/dist/middleware/steer-journey.d.ts +3 -2
  68. package/dist/middleware/steer-journey.js +26 -8
  69. package/dist/middleware/validate-fields.js +15 -21
  70. package/dist/mjs/esm-wrapper.js +18 -7
  71. package/dist/routes/ancillary.d.ts +8 -1
  72. package/dist/routes/ancillary.js +7 -1
  73. package/dist/routes/dirname.cjs +1 -1
  74. package/dist/routes/dirname.d.cts +2 -0
  75. package/dist/routes/journey.js +20 -24
  76. package/dist/routes/static.js +10 -9
  77. package/package.json +41 -22
  78. package/views/casa/errors/static.njk +11 -0
  79. package/views/casa/layouts/main.njk +3 -3
@@ -2,14 +2,14 @@ export default class MutableRouter {
2
2
  /**
3
3
  * Seals this router to make it immutable. Returns the ExpressJS router.
4
4
  *
5
- * @returns {Router}
5
+ * @returns {Router} ExpressJS Router
6
6
  */
7
7
  seal(): Router;
8
8
  /**
9
9
  * Prepend middleware function(s) using the `all()` method.
10
10
  *
11
11
  * @param {string} path route path
12
- * @param {...function} callbacks Middleware functions
12
+ * @param {...Function} callbacks Middleware functions
13
13
  * @returns {void}
14
14
  */
15
15
  prependAll(path: string, ...callbacks: Function[]): void;
@@ -17,7 +17,7 @@ export default class MutableRouter {
17
17
  * Prepend middleware function(s) using the `get()` method.
18
18
  *
19
19
  * @param {string} path route path
20
- * @param {...function} callbacks Middleware functions
20
+ * @param {...Function} callbacks Middleware functions
21
21
  * @returns {void}
22
22
  */
23
23
  prependGet(path: string, ...callbacks: Function[]): void;
@@ -25,7 +25,7 @@ export default class MutableRouter {
25
25
  * Prepend middleware function(s) using the `post()` method.
26
26
  *
27
27
  * @param {string} path route path
28
- * @param {...function} callbacks Middleware functions
28
+ * @param {...Function} callbacks Middleware functions
29
29
  * @returns {void}
30
30
  */
31
31
  prependPost(path: string, ...callbacks: Function[]): void;
@@ -33,7 +33,7 @@ export default class MutableRouter {
33
33
  * Prepend middleware function(s) using the `delete()` method.
34
34
  *
35
35
  * @param {string} path route path
36
- * @param {...function} callbacks Middleware functions
36
+ * @param {...Function} callbacks Middleware functions
37
37
  * @returns {void}
38
38
  */
39
39
  prependDelete(path: string, ...callbacks: Function[]): void;
@@ -41,7 +41,7 @@ export default class MutableRouter {
41
41
  * Prepend middleware function(s) using the `put()` method.
42
42
  *
43
43
  * @param {string} path route path
44
- * @param {...function} callbacks Middleware functions
44
+ * @param {...Function} callbacks Middleware functions
45
45
  * @returns {void}
46
46
  */
47
47
  prependPut(path: string, ...callbacks: Function[]): void;
@@ -49,7 +49,7 @@ export default class MutableRouter {
49
49
  * Prepend middleware function(s) using the `use()` method.
50
50
  *
51
51
  * @param {string} path route path
52
- * @param {...function} callbacks Middleware functions
52
+ * @param {...Function} callbacks Middleware functions
53
53
  * @returns {void}
54
54
  */
55
55
  prependUse(path: string, ...callbacks: Function[]): void;
@@ -57,7 +57,7 @@ export default class MutableRouter {
57
57
  * Replace middleware function(s) that were mounted using the `all()` method.
58
58
  *
59
59
  * @param {string} path route path
60
- * @param {...function} callbacks Middleware functions
60
+ * @param {...Function} callbacks Middleware functions
61
61
  * @returns {void}
62
62
  */
63
63
  replaceAll(path: string, ...callbacks: Function[]): void;
@@ -65,7 +65,7 @@ export default class MutableRouter {
65
65
  * Replace middleware function(s) that were mounted using the `get()` method.
66
66
  *
67
67
  * @param {string} path route path
68
- * @param {...function} callbacks Middleware functions
68
+ * @param {...Function} callbacks Middleware functions
69
69
  * @returns {void}
70
70
  */
71
71
  replaceGet(path: string, ...callbacks: Function[]): void;
@@ -73,7 +73,7 @@ export default class MutableRouter {
73
73
  * Replace middleware function(s) that were mounted using the `post()` method.
74
74
  *
75
75
  * @param {string} path route path
76
- * @param {...function} callbacks Middleware functions
76
+ * @param {...Function} callbacks Middleware functions
77
77
  * @returns {void}
78
78
  */
79
79
  replacePost(path: string, ...callbacks: Function[]): void;
@@ -81,7 +81,7 @@ export default class MutableRouter {
81
81
  * Replace middleware function(s) that were mounted using the `delete()` method.
82
82
  *
83
83
  * @param {string} path route path
84
- * @param {...function} callbacks Middleware functions
84
+ * @param {...Function} callbacks Middleware functions
85
85
  * @returns {void}
86
86
  */
87
87
  replaceDelete(path: string, ...callbacks: Function[]): void;
@@ -89,7 +89,7 @@ export default class MutableRouter {
89
89
  * Replace middleware function(s) that were mounted using the `put()` method.
90
90
  *
91
91
  * @param {string} path route path
92
- * @param {...function} callbacks Middleware functions
92
+ * @param {...Function} callbacks Middleware functions
93
93
  * @returns {void}
94
94
  */
95
95
  replacePut(path: string, ...callbacks: Function[]): void;
@@ -97,7 +97,7 @@ export default class MutableRouter {
97
97
  * Replace middleware function(s) that were mounted using the `use()` method.
98
98
  *
99
99
  * @param {string} path route path
100
- * @param {...function} callbacks Middleware functions
100
+ * @param {...Function} callbacks Middleware functions
101
101
  * @returns {void}
102
102
  */
103
103
  replaceUse(path: string, ...callbacks: Function[]): void;
@@ -105,7 +105,7 @@ export default class MutableRouter {
105
105
  * Append middleware function(s) using the `all()` method.
106
106
  *
107
107
  * @param {string} path route path
108
- * @param {...function} callbacks Middleware functions
108
+ * @param {...Function} callbacks Middleware functions
109
109
  * @returns {void}
110
110
  */
111
111
  all(path: string, ...callbacks: Function[]): void;
@@ -113,7 +113,7 @@ export default class MutableRouter {
113
113
  * Append middleware function(s) using the `get()` method.
114
114
  *
115
115
  * @param {string} path route path
116
- * @param {...function} callbacks Middleware functions
116
+ * @param {...Function} callbacks Middleware functions
117
117
  * @returns {void}
118
118
  */
119
119
  get(path: string, ...callbacks: Function[]): void;
@@ -121,7 +121,7 @@ export default class MutableRouter {
121
121
  * Append middleware function(s) using the `post()` method.
122
122
  *
123
123
  * @param {string} path route path
124
- * @param {...function} callbacks Middleware functions
124
+ * @param {...Function} callbacks Middleware functions
125
125
  * @returns {void}
126
126
  */
127
127
  post(path: string, ...callbacks: Function[]): void;
@@ -129,7 +129,7 @@ export default class MutableRouter {
129
129
  * Append middleware function(s) using the `delete()` method.
130
130
  *
131
131
  * @param {string} path route path
132
- * @param {...function} callbacks Middleware functions
132
+ * @param {...Function} callbacks Middleware functions
133
133
  * @returns {void}
134
134
  */
135
135
  delete(path: string, ...callbacks: Function[]): void;
@@ -137,7 +137,7 @@ export default class MutableRouter {
137
137
  * Append middleware function(s) using the `put()` method.
138
138
  *
139
139
  * @param {string} path route path
140
- * @param {...function} callbacks Middleware functions
140
+ * @param {...Function} callbacks Middleware functions
141
141
  * @returns {void}
142
142
  */
143
143
  put(path: string, ...callbacks: Function[]): void;
@@ -145,7 +145,7 @@ export default class MutableRouter {
145
145
  * Append middleware function(s) using the `use()` method.
146
146
  *
147
147
  * @param {string} path route path
148
- * @param {...function} callbacks Middleware functions
148
+ * @param {...Function} callbacks Middleware functions
149
149
  * @returns {void}
150
150
  */
151
151
  use(path: string, ...callbacks: Function[]): void;
@@ -12,15 +12,18 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
12
12
  };
13
13
  var _MutableRouter_instances, _MutableRouter_stack, _MutableRouter_router, _MutableRouter_sealed, _MutableRouter_append, _MutableRouter_prepend, _MutableRouter_replace;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
+ /* eslint-disable sonarjs/no-duplicate-string,class-methods-use-this */
15
16
  const express_1 = require("express");
16
17
  class MutableRouter {
17
18
  /**
19
+ * Mutable router.
20
+ *
18
21
  * @class
19
22
  */
20
23
  constructor() {
21
24
  _MutableRouter_instances.add(this);
22
25
  /**
23
- * @type {array}
26
+ * @type {Array}
24
27
  */
25
28
  _MutableRouter_stack.set(this, void 0);
26
29
  /**
@@ -38,13 +41,16 @@ class MutableRouter {
38
41
  /**
39
42
  * Seals this router to make it immutable. Returns the ExpressJS router.
40
43
  *
41
- * @returns {Router}
44
+ * @returns {Router} ExpressJS Router
42
45
  */
43
46
  seal() {
44
47
  if (__classPrivateFieldGet(this, _MutableRouter_sealed, "f")) {
45
48
  return __classPrivateFieldGet(this, _MutableRouter_router, "f");
46
49
  }
47
50
  __classPrivateFieldGet(this, _MutableRouter_stack, "f").forEach(({ method, args }) => {
51
+ // ESLint disabled as `#router` is dev-controlled, and `seal()` is only
52
+ // run at boot-time before any user interaction
53
+ /* eslint-disable-next-line security/detect-object-injection */
48
54
  __classPrivateFieldGet(this, _MutableRouter_router, "f")[method].call(__classPrivateFieldGet(this, _MutableRouter_router, "f"), ...args);
49
55
  });
50
56
  __classPrivateFieldSet(this, _MutableRouter_sealed, true, "f");
@@ -55,7 +61,7 @@ class MutableRouter {
55
61
  * Prepend middleware function(s) using the `all()` method.
56
62
  *
57
63
  * @param {string} path route path
58
- * @param {...function} callbacks Middleware functions
64
+ * @param {...Function} callbacks Middleware functions
59
65
  * @returns {void}
60
66
  */
61
67
  prependAll(path, ...callbacks) {
@@ -65,7 +71,7 @@ class MutableRouter {
65
71
  * Prepend middleware function(s) using the `get()` method.
66
72
  *
67
73
  * @param {string} path route path
68
- * @param {...function} callbacks Middleware functions
74
+ * @param {...Function} callbacks Middleware functions
69
75
  * @returns {void}
70
76
  */
71
77
  prependGet(path, ...callbacks) {
@@ -75,7 +81,7 @@ class MutableRouter {
75
81
  * Prepend middleware function(s) using the `post()` method.
76
82
  *
77
83
  * @param {string} path route path
78
- * @param {...function} callbacks Middleware functions
84
+ * @param {...Function} callbacks Middleware functions
79
85
  * @returns {void}
80
86
  */
81
87
  prependPost(path, ...callbacks) {
@@ -85,7 +91,7 @@ class MutableRouter {
85
91
  * Prepend middleware function(s) using the `delete()` method.
86
92
  *
87
93
  * @param {string} path route path
88
- * @param {...function} callbacks Middleware functions
94
+ * @param {...Function} callbacks Middleware functions
89
95
  * @returns {void}
90
96
  */
91
97
  prependDelete(path, ...callbacks) {
@@ -95,7 +101,7 @@ class MutableRouter {
95
101
  * Prepend middleware function(s) using the `put()` method.
96
102
  *
97
103
  * @param {string} path route path
98
- * @param {...function} callbacks Middleware functions
104
+ * @param {...Function} callbacks Middleware functions
99
105
  * @returns {void}
100
106
  */
101
107
  prependPut(path, ...callbacks) {
@@ -105,19 +111,18 @@ class MutableRouter {
105
111
  * Prepend middleware function(s) using the `use()` method.
106
112
  *
107
113
  * @param {string} path route path
108
- * @param {...function} callbacks Middleware functions
114
+ * @param {...Function} callbacks Middleware functions
109
115
  * @returns {void}
110
116
  */
111
117
  prependUse(path, ...callbacks) {
112
118
  __classPrivateFieldGet(this, _MutableRouter_instances, "m", _MutableRouter_prepend).call(this, 'use', path, ...callbacks);
113
119
  }
114
120
  /* -------------------------------------------------------------- replacers */
115
- // TODO: How do we handle multiple routes on the same path?
116
121
  /**
117
122
  * Replace middleware function(s) that were mounted using the `all()` method.
118
123
  *
119
124
  * @param {string} path route path
120
- * @param {...function} callbacks Middleware functions
125
+ * @param {...Function} callbacks Middleware functions
121
126
  * @returns {void}
122
127
  */
123
128
  replaceAll(path, ...callbacks) {
@@ -127,7 +132,7 @@ class MutableRouter {
127
132
  * Replace middleware function(s) that were mounted using the `get()` method.
128
133
  *
129
134
  * @param {string} path route path
130
- * @param {...function} callbacks Middleware functions
135
+ * @param {...Function} callbacks Middleware functions
131
136
  * @returns {void}
132
137
  */
133
138
  replaceGet(path, ...callbacks) {
@@ -137,7 +142,7 @@ class MutableRouter {
137
142
  * Replace middleware function(s) that were mounted using the `post()` method.
138
143
  *
139
144
  * @param {string} path route path
140
- * @param {...function} callbacks Middleware functions
145
+ * @param {...Function} callbacks Middleware functions
141
146
  * @returns {void}
142
147
  */
143
148
  replacePost(path, ...callbacks) {
@@ -147,7 +152,7 @@ class MutableRouter {
147
152
  * Replace middleware function(s) that were mounted using the `delete()` method.
148
153
  *
149
154
  * @param {string} path route path
150
- * @param {...function} callbacks Middleware functions
155
+ * @param {...Function} callbacks Middleware functions
151
156
  * @returns {void}
152
157
  */
153
158
  replaceDelete(path, ...callbacks) {
@@ -157,7 +162,7 @@ class MutableRouter {
157
162
  * Replace middleware function(s) that were mounted using the `put()` method.
158
163
  *
159
164
  * @param {string} path route path
160
- * @param {...function} callbacks Middleware functions
165
+ * @param {...Function} callbacks Middleware functions
161
166
  * @returns {void}
162
167
  */
163
168
  replacePut(path, ...callbacks) {
@@ -167,7 +172,7 @@ class MutableRouter {
167
172
  * Replace middleware function(s) that were mounted using the `use()` method.
168
173
  *
169
174
  * @param {string} path route path
170
- * @param {...function} callbacks Middleware functions
175
+ * @param {...Function} callbacks Middleware functions
171
176
  * @returns {void}
172
177
  */
173
178
  replaceUse(path, ...callbacks) {
@@ -178,7 +183,7 @@ class MutableRouter {
178
183
  * Append middleware function(s) using the `all()` method.
179
184
  *
180
185
  * @param {string} path route path
181
- * @param {...function} callbacks Middleware functions
186
+ * @param {...Function} callbacks Middleware functions
182
187
  * @returns {void}
183
188
  */
184
189
  all(path, ...callbacks) {
@@ -188,7 +193,7 @@ class MutableRouter {
188
193
  * Append middleware function(s) using the `get()` method.
189
194
  *
190
195
  * @param {string} path route path
191
- * @param {...function} callbacks Middleware functions
196
+ * @param {...Function} callbacks Middleware functions
192
197
  * @returns {void}
193
198
  */
194
199
  get(path, ...callbacks) {
@@ -198,7 +203,7 @@ class MutableRouter {
198
203
  * Append middleware function(s) using the `post()` method.
199
204
  *
200
205
  * @param {string} path route path
201
- * @param {...function} callbacks Middleware functions
206
+ * @param {...Function} callbacks Middleware functions
202
207
  * @returns {void}
203
208
  */
204
209
  post(path, ...callbacks) {
@@ -208,7 +213,7 @@ class MutableRouter {
208
213
  * Append middleware function(s) using the `delete()` method.
209
214
  *
210
215
  * @param {string} path route path
211
- * @param {...function} callbacks Middleware functions
216
+ * @param {...Function} callbacks Middleware functions
212
217
  * @returns {void}
213
218
  */
214
219
  delete(path, ...callbacks) {
@@ -218,7 +223,7 @@ class MutableRouter {
218
223
  * Append middleware function(s) using the `put()` method.
219
224
  *
220
225
  * @param {string} path route path
221
- * @param {...function} callbacks Middleware functions
226
+ * @param {...Function} callbacks Middleware functions
222
227
  * @returns {void}
223
228
  */
224
229
  put(path, ...callbacks) {
@@ -228,14 +233,14 @@ class MutableRouter {
228
233
  * Append middleware function(s) using the `use()` method.
229
234
  *
230
235
  * @param {string} path route path
231
- * @param {...function} callbacks Middleware functions
236
+ * @param {...Function} callbacks Middleware functions
232
237
  * @returns {void}
233
238
  */
234
239
  use(path, ...callbacks) {
235
240
  __classPrivateFieldGet(this, _MutableRouter_instances, "m", _MutableRouter_append).call(this, 'use', path, ...callbacks);
236
241
  }
237
242
  route() {
238
- throw new Error('The route() method is not currently supported on the MutableRouter class. Please use the verb methods for now.');
243
+ throw new Error('route() method is not supported on MutableRouter. Use verb methods for now.');
239
244
  }
240
245
  }
241
246
  exports.default = MutableRouter;
@@ -261,12 +266,14 @@ _MutableRouter_stack = new WeakMap(), _MutableRouter_router = new WeakMap(), _Mu
261
266
  if (__classPrivateFieldGet(this, _MutableRouter_sealed, "f")) {
262
267
  throw new Error('Cannot alter middleware in a sealed mutable router');
263
268
  }
264
- const index = __classPrivateFieldGet(this, _MutableRouter_stack, "f").findIndex((command) => `${command.method}|${command.path}` === `${method}|${path}`);
269
+ const finder = (command) => `${command.method}|${command.path}` === `${method}|${path}`;
270
+ const index = __classPrivateFieldGet(this, _MutableRouter_stack, "f").findIndex(finder);
265
271
  if (index > -1) {
266
272
  __classPrivateFieldGet(this, _MutableRouter_stack, "f").splice(index, 1, {
267
273
  method,
268
274
  path,
269
275
  args: [path, ...callbacks],
270
276
  });
277
+ __classPrivateFieldSet(this, _MutableRouter_stack, __classPrivateFieldGet(this, _MutableRouter_stack, "f").filter((command, idx) => idx <= index || !finder(command)), "f");
271
278
  }
272
279
  };
@@ -1,10 +1,44 @@
1
1
  export default class Plan {
2
- static isExitNode(name: any): boolean;
3
2
  /**
4
- * @param {object} opts
3
+ * Waypoints using the url:// protocol are known as "exit nodes" as they
4
+ * indicate an exit point to another Plan.
5
+ *
6
+ * @param {string} name Waypoint name
7
+ * @returns {boolean} True if the waypoint is a url:// type
8
+ */
9
+ static isExitNode(name: string): boolean;
10
+ /**
11
+ * Create a Plan.
12
+ *
13
+ * @param {object} opts Options
14
+ * @param {boolean} [opts.validateBeforeRouteCondition=true] Check page validity before conditions
15
+ * @param {Function|string} [opts.arbiter=undefined] Arbitration mechanism
5
16
  */
6
- constructor(opts?: object);
17
+ constructor(opts?: {
18
+ validateBeforeRouteCondition?: boolean | undefined;
19
+ arbiter?: string | Function | undefined;
20
+ });
7
21
  getOptions(): any;
22
+ /**
23
+ * Retrieve the list of skippable waypoints.
24
+ *
25
+ * @returns {string[]} List of skippable waypoints
26
+ */
27
+ getSkippables(): string[];
28
+ /**
29
+ * Add one or more skippable waypoints.
30
+ *
31
+ * @param {...string} waypoints Waypoints
32
+ * @returns {Plan}{ Chain}
33
+ */
34
+ addSkippables(...waypoints: string[]): Plan;
35
+ /**
36
+ * Check if the user can skip the named waypoint.
37
+ *
38
+ * @param {string} waypoint Waypoint
39
+ * @returns {boolean} True if waypoint can be skipped
40
+ */
41
+ isSkippable(waypoint: string): boolean;
8
42
  getWaypoints(): any;
9
43
  containsWaypoint(waypoint: any): any;
10
44
  getRoutes(): any;
@@ -100,7 +134,7 @@ export default class Plan {
100
134
  * string routeName = Follow routes matching this name (next | prev)
101
135
  * Map history = Used to detect loops in traversal (internal use)
102
136
  * function stopCondition = Condition that, if true, will stop traversal (useful for performance)
103
- * function|string arbiter = When mutliple target routes are found, this will decide which one to choose (if any)
137
+ * function|string arbiter = If mutliple target routes found, this decides which to use (if any)
104
138
  *
105
139
  * @param {JourneyContext} context Journey context
106
140
  * @param {object} options Options
@@ -112,8 +146,9 @@ export default class Plan {
112
146
  * Get raw graph data structure. This can be used with other libraries to
113
147
  * generate graph visualisations, for example.
114
148
  *
115
- * @returns {graphlib.Graph} Graph data structure.
149
+ * @returns {Graph} Graph data structure.
116
150
  */
117
- getGraphStructure(): any;
151
+ getGraphStructure(): Graph;
152
+ #private;
118
153
  }
119
154
  import JourneyContext from "./JourneyContext.js";
package/dist/lib/Plan.js CHANGED
@@ -1,12 +1,24 @@
1
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
+ };
2
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
15
  };
16
+ var _Plan_skippableWaypoints;
5
17
  Object.defineProperty(exports, "__esModule", { value: true });
6
18
  const graphlib_1 = require("graphlib");
7
19
  const JourneyContext_js_1 = __importDefault(require("./JourneyContext.js"));
8
20
  const logger_js_1 = __importDefault(require("./logger.js"));
9
- const log = (0, logger_js_1.default)('class:plan');
21
+ const log = (0, logger_js_1.default)('lib:plan');
10
22
  /**
11
23
  * Will check if the source waypoint has specifically passed validation, i.e
12
24
  * there is a "null" validation entry for the route source.
@@ -35,6 +47,9 @@ function validateWaypointId(val) {
35
47
  if (typeof val !== 'string') {
36
48
  throw new TypeError(`Expected waypoint id to be a string, got ${typeof val}`);
37
49
  }
50
+ if (val.substr(0, 6) === 'url://' && !val.endsWith('/')) {
51
+ throw new SyntaxError('url:// waypoints must include a trailing /');
52
+ }
38
53
  }
39
54
  function validateRouteName(val) {
40
55
  if (typeof val !== 'string') {
@@ -43,6 +58,7 @@ function validateRouteName(val) {
43
58
  else if (!['next', 'prev'].includes(val)) {
44
59
  throw new ReferenceError(`Expected route name to be one of next or prev. Got ${val}`);
45
60
  }
61
+ return val;
46
62
  }
47
63
  function validateRouteCondition(val) {
48
64
  if (!(val instanceof Function)) {
@@ -74,13 +90,18 @@ const makeRouteObject = (dgraph, edge) => {
74
90
  const reExitNodeProtocol = /^[a-z]+:\/\//i;
75
91
  const priv = new WeakMap();
76
92
  class Plan {
77
- static isExitNode(name) {
78
- return reExitNodeProtocol.test(name);
79
- }
80
93
  /**
81
- * @param {object} opts
94
+ * Create a Plan.
95
+ *
96
+ * @param {object} opts Options
97
+ * @param {boolean} [opts.validateBeforeRouteCondition=true] Check page validity before conditions
98
+ * @param {Function|string} [opts.arbiter=undefined] Arbitration mechanism
82
99
  */
83
100
  constructor(opts = {}) {
101
+ /**
102
+ * @type {string[]} These waypoints can be skipped
103
+ */
104
+ _Plan_skippableWaypoints.set(this, void 0);
84
105
  // This is our directed, multigraph representation
85
106
  const dgraph = new graphlib_1.Graph({
86
107
  directed: true,
@@ -104,10 +125,48 @@ class Plan {
104
125
  },
105
126
  options,
106
127
  });
128
+ __classPrivateFieldSet(this, _Plan_skippableWaypoints, [], "f");
129
+ }
130
+ /**
131
+ * Waypoints using the url:// protocol are known as "exit nodes" as they
132
+ * indicate an exit point to another Plan.
133
+ *
134
+ * @param {string} name Waypoint name
135
+ * @returns {boolean} True if the waypoint is a url:// type
136
+ */
137
+ static isExitNode(name) {
138
+ return reExitNodeProtocol.test(name);
107
139
  }
108
140
  getOptions() {
109
141
  return priv.get(this).options;
110
142
  }
143
+ /**
144
+ * Retrieve the list of skippable waypoints.
145
+ *
146
+ * @returns {string[]} List of skippable waypoints
147
+ */
148
+ getSkippables() {
149
+ return __classPrivateFieldGet(this, _Plan_skippableWaypoints, "f");
150
+ }
151
+ /**
152
+ * Add one or more skippable waypoints.
153
+ *
154
+ * @param {...string} waypoints Waypoints
155
+ * @returns {Plan}{ Chain}
156
+ */
157
+ addSkippables(...waypoints) {
158
+ __classPrivateFieldSet(this, _Plan_skippableWaypoints, [...__classPrivateFieldGet(this, _Plan_skippableWaypoints, "f"), ...waypoints], "f");
159
+ return this;
160
+ }
161
+ /**
162
+ * Check if the user can skip the named waypoint.
163
+ *
164
+ * @param {string} waypoint Waypoint
165
+ * @returns {boolean} True if waypoint can be skipped
166
+ */
167
+ isSkippable(waypoint) {
168
+ return __classPrivateFieldGet(this, _Plan_skippableWaypoints, "f").indexOf(waypoint) > -1;
169
+ }
111
170
  getWaypoints() {
112
171
  return priv.get(this).dgraph.nodes();
113
172
  }
@@ -119,7 +178,7 @@ class Plan {
119
178
  return self.dgraph.edges().map((edge) => makeRouteObject(self.dgraph, edge));
120
179
  }
121
180
  getRouteCondition(src, tgt, name) {
122
- return priv.get(this).follows[name][`${src}/${tgt}`];
181
+ return priv.get(this).follows[validateRouteName(name)][`${src}/${tgt}`];
123
182
  }
124
183
  /**
125
184
  * Return all outward routes (out-edges) from the given waypoint, to the
@@ -147,6 +206,8 @@ class Plan {
147
206
  addSequence(...waypoints) {
148
207
  // Setup simple double routes (next/prev) between all waypoints in this list
149
208
  for (let i = 0, l = waypoints.length - 1; i < l; i += 1) {
209
+ // ESLint disabled as `i` is an integer
210
+ /* eslint-disable-next-line security/detect-object-injection */
150
211
  this.setRoute(waypoints[i], waypoints[i + 1]);
151
212
  }
152
213
  }
@@ -180,13 +241,14 @@ class Plan {
180
241
  */
181
242
  setRoute(src, tgt, followNext = undefined, followPrev = undefined) {
182
243
  this.setNamedRoute(src, tgt, 'next', followNext);
183
- if (followPrev === undefined) {
184
- followPrev = followNext === undefined ? undefined : (r, c) => {
244
+ let followPrevious = followPrev;
245
+ if (followPrevious === undefined) {
246
+ followPrevious = followNext === undefined ? undefined : (r, c) => {
185
247
  const invertedRoute = Object.assign(Object.assign({}, r), { source: r.target, target: r.source });
186
248
  return followNext(invertedRoute, c);
187
249
  };
188
250
  }
189
- this.setNamedRoute(tgt, src, 'prev', followPrev);
251
+ this.setNamedRoute(tgt, src, 'prev', followPrevious);
190
252
  return this;
191
253
  }
192
254
  /**
@@ -219,12 +281,12 @@ class Plan {
219
281
  validateRouteCondition(follow);
220
282
  }
221
283
  // Get routing function name to label edge
222
- const label = follow && follow.name;
284
+ const conditionName = follow && follow.name;
223
285
  // Warn if we're overwriting an existing edge on the same name
224
286
  if (self.dgraph.hasEdge(src, tgt, name)) {
225
287
  log.warn('Setting a route that already exists (%s, %s, %s). Will be overridden', src, tgt, name);
226
288
  }
227
- self.dgraph.setEdge(src, tgt, { label }, name);
289
+ self.dgraph.setEdge(src, tgt, { conditionName }, name);
228
290
  // Determine which follow function to use
229
291
  let followFunc;
230
292
  if (follow) {
@@ -250,6 +312,8 @@ class Plan {
250
312
  else {
251
313
  followFunc = defaultPrevFollow;
252
314
  }
315
+ // ESLint disabled as `name` has been validated further above
316
+ /* eslint-disable-next-line security/detect-object-injection */
253
317
  self.follows[name][`${src}/${tgt}`] = followFunc;
254
318
  return this;
255
319
  }
@@ -285,7 +349,7 @@ class Plan {
285
349
  * string routeName = Follow routes matching this name (next | prev)
286
350
  * Map history = Used to detect loops in traversal (internal use)
287
351
  * function stopCondition = Condition that, if true, will stop traversal (useful for performance)
288
- * function|string arbiter = When mutliple target routes are found, this will decide which one to choose (if any)
352
+ * function|string arbiter = If mutliple target routes found, this decides which to use (if any)
289
353
  *
290
354
  * @param {JourneyContext} context Journey context
291
355
  * @param {object} options Options
@@ -301,9 +365,7 @@ class Plan {
301
365
  if (!self.dgraph.hasNode(startWaypoint)) {
302
366
  throw new ReferenceError(`Plan does not contain waypoint '${startWaypoint}'`);
303
367
  }
304
- if (routeName === undefined) {
305
- throw new ReferenceError('Route name must be provided');
306
- }
368
+ validateRouteName(routeName);
307
369
  const history = new Map();
308
370
  const traverse = (startWP) => {
309
371
  let target = self.dgraph.outEdges(startWP).filter((e) => {
@@ -312,6 +374,8 @@ class Plan {
312
374
  }
313
375
  const route = makeRouteObject(self.dgraph, e);
314
376
  try {
377
+ // ESLint disabled as `routeName` has been validated further above
378
+ /* eslint-disable-next-line security/detect-object-injection */
315
379
  return self.follows[routeName][`${e.v}/${e.w}`](route, context);
316
380
  }
317
381
  catch (ex) {
@@ -330,7 +394,7 @@ class Plan {
330
394
  stopCondition: ({ source }) => targetNames.includes(source),
331
395
  });
332
396
  const resolved = forwardTraversal.pop();
333
- target = target.filter(t => t.w === resolved.source);
397
+ target = target.filter((t) => t.w === resolved.source);
334
398
  }
335
399
  else if (arbiter instanceof Function) {
336
400
  log.debug('Using custom arbitration process');
@@ -354,6 +418,8 @@ class Plan {
354
418
  const results = new Array(totalTrav + 1);
355
419
  results[0] = route;
356
420
  for (let i = 0; i < totalTrav; i++) {
421
+ // ESLint disabled as `i` is an integer
422
+ /* eslint-disable-next-line security/detect-object-injection */
357
423
  results[i + 1] = traversed[i];
358
424
  }
359
425
  return results;
@@ -373,10 +439,11 @@ class Plan {
373
439
  * Get raw graph data structure. This can be used with other libraries to
374
440
  * generate graph visualisations, for example.
375
441
  *
376
- * @returns {graphlib.Graph} Graph data structure.
442
+ * @returns {Graph} Graph data structure.
377
443
  */
378
444
  getGraphStructure() {
379
445
  return priv.get(this).dgraph;
380
446
  }
381
447
  }
382
448
  exports.default = Plan;
449
+ _Plan_skippableWaypoints = new WeakMap();