@dwp/govuk-casa 8.2.3 → 8.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +1 -0
  2. package/dist/casa.d.ts +198 -0
  3. package/dist/casa.js +129 -0
  4. package/dist/lib/CasaTemplateLoader.d.ts +4 -0
  5. package/dist/lib/CasaTemplateLoader.js +5 -0
  6. package/dist/lib/JourneyContext.d.ts +85 -13
  7. package/dist/lib/JourneyContext.js +78 -5
  8. package/dist/lib/Plan.d.ts +122 -49
  9. package/dist/lib/Plan.js +161 -37
  10. package/dist/lib/ValidationError.d.ts +38 -48
  11. package/dist/lib/ValidationError.js +30 -42
  12. package/dist/lib/ValidatorFactory.d.ts +42 -52
  13. package/dist/lib/ValidatorFactory.js +37 -48
  14. package/dist/lib/configuration-ingestor.d.ts +15 -0
  15. package/dist/lib/configuration-ingestor.js +17 -0
  16. package/dist/lib/configure.d.ts +4 -0
  17. package/dist/lib/configure.js +14 -1
  18. package/dist/lib/end-session.d.ts +3 -2
  19. package/dist/lib/end-session.js +2 -1
  20. package/dist/lib/field.d.ts +97 -35
  21. package/dist/lib/field.js +90 -41
  22. package/dist/lib/nunjucks-filters.d.ts +12 -2
  23. package/dist/lib/nunjucks-filters.js +11 -1
  24. package/dist/lib/nunjucks.d.ts +1 -0
  25. package/dist/lib/nunjucks.js +1 -0
  26. package/dist/lib/utils.d.ts +46 -14
  27. package/dist/lib/utils.js +43 -26
  28. package/dist/lib/validators/dateObject.d.ts +75 -1
  29. package/dist/lib/validators/dateObject.js +29 -18
  30. package/dist/lib/validators/email.d.ts +28 -1
  31. package/dist/lib/validators/email.js +20 -9
  32. package/dist/lib/validators/inArray.d.ts +34 -1
  33. package/dist/lib/validators/inArray.js +21 -0
  34. package/dist/lib/validators/index.js +3 -0
  35. package/dist/lib/validators/nino.d.ts +34 -1
  36. package/dist/lib/validators/nino.js +17 -7
  37. package/dist/lib/validators/postalAddressObject.d.ts +68 -1
  38. package/dist/lib/validators/postalAddressObject.js +27 -15
  39. package/dist/lib/validators/regex.d.ts +35 -1
  40. package/dist/lib/validators/regex.js +17 -7
  41. package/dist/lib/validators/required.d.ts +28 -1
  42. package/dist/lib/validators/required.js +19 -6
  43. package/dist/lib/validators/strlen.d.ts +40 -1
  44. package/dist/lib/validators/strlen.js +18 -8
  45. package/dist/lib/validators/wordCount.d.ts +40 -1
  46. package/dist/lib/validators/wordCount.js +18 -8
  47. package/dist/lib/waypoint-url.d.ts +1 -0
  48. package/dist/lib/waypoint-url.js +10 -0
  49. package/dist/middleware/data.js +21 -5
  50. package/dist/middleware/gather-fields.js +1 -0
  51. package/dist/middleware/pre.js +1 -0
  52. package/dist/middleware/steer-journey.js +2 -1
  53. package/dist/middleware/strip-proxy-path.js +6 -2
  54. package/dist/middleware/validate-fields.js +3 -0
  55. package/dist/routes/ancillary.d.ts +16 -5
  56. package/dist/routes/ancillary.js +7 -3
  57. package/dist/routes/journey.d.ts +30 -6
  58. package/dist/routes/journey.js +27 -0
  59. package/dist/routes/static.d.ts +1 -0
  60. package/dist/routes/static.js +2 -1
  61. package/package.json +16 -11
  62. package/views/casa/components/character-count/README.md +1 -1
  63. package/views/casa/components/input/README.md +1 -1
  64. package/views/casa/components/radios/README.md +2 -2
  65. package/views/casa/components/textarea/README.md +1 -1
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @memberof module:@dwp/govuk-casa
3
+ */
1
4
  export default class Plan {
2
5
  /**
3
6
  * Waypoints using the url:// protocol are known as "exit nodes" as they
@@ -10,15 +13,15 @@ export default class Plan {
10
13
  /**
11
14
  * Create a Plan.
12
15
  *
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
16
+ * @param {PlanConstructorOptions} opts Options
16
17
  */
17
- constructor(opts?: {
18
- validateBeforeRouteCondition?: boolean | undefined;
19
- arbiter?: string | Function | undefined;
20
- });
21
- getOptions(): any;
18
+ constructor(opts?: PlanConstructorOptions);
19
+ /**
20
+ * Retrieve the options set on this Plan.
21
+ *
22
+ * @returns {PlanConstructorOptions} Options map
23
+ */
24
+ getOptions(): PlanConstructorOptions;
22
25
  /**
23
26
  * Retrieve the list of skippable waypoints.
24
27
  *
@@ -29,7 +32,7 @@ export default class Plan {
29
32
  * Add one or more skippable waypoints.
30
33
  *
31
34
  * @param {...string} waypoints Waypoints
32
- * @returns {Plan}{ Chain}
35
+ * @returns {Plan} Chain
33
36
  */
34
37
  addSkippables(...waypoints: string[]): Plan;
35
38
  /**
@@ -39,40 +42,87 @@ export default class Plan {
39
42
  * @returns {boolean} True if waypoint can be skipped
40
43
  */
41
44
  isSkippable(waypoint: string): boolean;
42
- getWaypoints(): any;
43
- containsWaypoint(waypoint: any): any;
44
- getRoutes(): any;
45
- getRouteCondition(src: any, tgt: any, name: any): any;
45
+ /**
46
+ * Retrieve all waypoints in this Plan (order is arbitrary).
47
+ *
48
+ * @returns {string[]} List of waypoints
49
+ */
50
+ getWaypoints(): string[];
51
+ /**
52
+ * Determine if the given waypoint exists in this Plan.
53
+ *
54
+ * @param {string} waypoint Waypoint to search for
55
+ * @returns {boolean} Result
56
+ */
57
+ containsWaypoint(waypoint: string): boolean;
58
+ /**
59
+ * Get all route information.
60
+ *
61
+ * @returns {PlanRoute[]} Routes
62
+ */
63
+ getRoutes(): PlanRoute[];
64
+ /**
65
+ * Get the condition function for the given parameters.
66
+ *
67
+ * @param {string} src Source waypoint
68
+ * @param {string} tgt Target waypoint
69
+ * @param {string} name Route name
70
+ * @returns {PlanRouteCondition} Route condition function
71
+ */
72
+ getRouteCondition(src: string, tgt: string, name: string): PlanRouteCondition;
46
73
  /**
47
74
  * Return all outward routes (out-edges) from the given waypoint, to the
48
75
  * optional target waypoint.
49
76
  *
50
77
  * @param {string} src Source waypoint.
51
- * @param {string} tgt Target waypoint (optional).
52
- * @returns {Array<object>} Route objects found.
78
+ * @param {string} [tgt] Target waypoint.
79
+ * @returns {PlanRoute[]} Route objects found.
53
80
  */
54
- getOutwardRoutes(src: string, tgt?: string): Array<object>;
81
+ getOutwardRoutes(src: string, tgt?: string | undefined): PlanRoute[];
55
82
  /**
56
83
  * Return all outward routes (out-edges) from the given waypoint, to the
57
84
  * optional target waypoint, matching the "prev" name.
58
85
  *
59
86
  * @param {string} src Source waypoint.
60
- * @param {string} tgt Target waypoint (optional).
61
- * @returns {Array<object>} Route objects found.
87
+ * @param {string} [tgt] Target waypoint.
88
+ * @returns {PlanRoute[]} Route objects found.
62
89
  */
63
- getPrevOutwardRoutes(src: string, tgt?: string): Array<object>;
64
- addSequence(...waypoints: any[]): void;
65
- setNextRoute(src: any, tgt: any, follow: any): Plan;
66
- setPrevRoute(src: any, tgt: any, follow: any): Plan;
90
+ getPrevOutwardRoutes(src: string, tgt?: string | undefined): PlanRoute[];
91
+ /**
92
+ * Add a sequence of waypoints that will follow on from each other, with no
93
+ * routing logic between them.
94
+ *
95
+ * @param {...string} waypoints Waypoints to add
96
+ * @returns {void}
97
+ */
98
+ addSequence(...waypoints: string[]): void;
99
+ /**
100
+ * Create a new directed route between two waypoints, labelled as "next".
101
+ *
102
+ * @param {string} src Source waypoint
103
+ * @param {string} tgt Target waypoint
104
+ * @param {PlanRouteCondition} follow Route condition function
105
+ * @returns {Plan} Chain
106
+ */
107
+ setNextRoute(src: string, tgt: string, follow: PlanRouteCondition): Plan;
108
+ /**
109
+ * Create a new directed route between two waypoints, labelled as "prev".
110
+ *
111
+ * @param {string} src Source waypoint
112
+ * @param {string} tgt Target waypoint
113
+ * @param {PlanRouteCondition} follow Route condition function
114
+ * @returns {Plan} Chain
115
+ */
116
+ setPrevRoute(src: string, tgt: string, follow: PlanRouteCondition): Plan;
67
117
  /**
68
118
  * Adds both a "next" and "prev" route between the two waypoints.
69
119
  *
70
- * By default, the "prev" route will use the same "follow" test as the "next"
71
- * route. This makes sense in that in order to get the target, the test must
72
- * have been true, and so to reverse the direction we also need that same test
73
- * to be true.
120
+ * By default, the "prev" route will use the same "follow" condition as the
121
+ * "next" route. This makes sense in that in order to get to the target, the
122
+ * condition must be true, and so to reverse the direction we also need that
123
+ * same condition to be true.
74
124
  *
75
- * However, if the condition function uses the `source`/`target`
125
+ * However, if the condition function uses the `source`/`target` property
76
126
  * of the route in some way, then we must reverse these before passing to the
77
127
  * condition on the "prev" route because `source` in the condition will almost
78
128
  * certainly be referring to the source of the "next" route.
@@ -82,11 +132,11 @@ export default class Plan {
82
132
  *
83
133
  * @param {string} src Source waypoint.
84
134
  * @param {string} tgt Target waypoint.
85
- * @param {Function} followNext Follow test function.
86
- * @param {Function} followPrev Follow test function.
87
- * @returns {Plan} Self.
135
+ * @param {PlanRouteCondition} [followNext] Follow test function.
136
+ * @param {PlanRouteCondition} [followPrev] Follow test function.
137
+ * @returns {Plan} Chain
88
138
  */
89
- setRoute(src: string, tgt: string, followNext?: Function, followPrev?: Function): Plan;
139
+ setRoute(src: string, tgt: string, followNext?: import("../casa").PlanRouteCondition | undefined, followPrev?: import("../casa").PlanRouteCondition | undefined): Plan;
90
140
  /**
91
141
  * Create a named route between two waypoints, and give that route a function
92
142
  * that determine whether it should be followed during traversal operations.
@@ -103,22 +153,38 @@ export default class Plan {
103
153
  * @param {string} src Source waypoint.
104
154
  * @param {string} tgt Target waypoint.
105
155
  * @param {string} name Name of the route (must be unique for this waypoint pairing).
106
- * @param {Function} follow Test function to determine if route can be followed.
156
+ * @param {PlanRouteCondition} follow Test function to determine if route can be followed.
107
157
  * @returns {Plan} Chain
108
158
  * @throws {Error} If attempting to create a "next" route from an exit node
109
159
  */
110
- setNamedRoute(src: string, tgt: string, name: string, follow: Function): Plan;
160
+ setNamedRoute(src: string, tgt: string, name: string, follow: PlanRouteCondition): Plan;
111
161
  /**
112
162
  * This is a convenience method for traversing all "next" routes, and returning
113
163
  * the IDs of all waypoints visited along the way.
114
164
  *
115
- * @param {JourneyContext} context Journey Context.
116
- * @param {object} options Options.
117
- * @returns {Array<string>} List of traversed waypoints.
165
+ * @param {JourneyContext} context Journey Context
166
+ * @param {PlanTraverseOptions} options Options
167
+ * @returns {string[]} List of traversed waypoints
118
168
  */
119
- traverse(context: JourneyContext, options?: object): Array<string>;
120
- traverseNextRoutes(context: any, options?: {}): object[];
121
- traversePrevRoutes(context: any, options?: {}): object[];
169
+ traverse(context: JourneyContext, options?: PlanTraverseOptions): string[];
170
+ /**
171
+ * Traverse the Plan by following all "next" routes, and returning the IDs of
172
+ * all waypoints visited along the way.
173
+ *
174
+ * @param {JourneyContext} context Journey Context
175
+ * @param {PlanTraverseOptions} options Options
176
+ * @returns {PlanRoute[]} List of traversed waypoints
177
+ */
178
+ traverseNextRoutes(context: JourneyContext, options?: PlanTraverseOptions): PlanRoute[];
179
+ /**
180
+ * Traverse the Plan by following all "prev" routes, and returning the IDs of
181
+ * all waypoints visited along the way.
182
+ *
183
+ * @param {JourneyContext} context Journey Context
184
+ * @param {PlanTraverseOptions} options Options
185
+ * @returns {PlanRoute[]} List of traversed waypoints
186
+ */
187
+ traversePrevRoutes(context: JourneyContext, options?: PlanTraverseOptions): PlanRoute[];
122
188
  /**
123
189
  * Traverse through the plan from a particular starting waypoint. This is a
124
190
  * non-exhaustive Graph Exploration.
@@ -129,19 +195,12 @@ export default class Plan {
129
195
  * If a cyclical set of routes are encountered, traversal will stop after
130
196
  * reaching the first repeated waypoint.
131
197
  *
132
- * Options:
133
- * string startWaypoint = Waypoint from which to start traversal
134
- * string routeName = Follow routes matching this name (next | prev)
135
- * Map history = Used to detect loops in traversal (internal use)
136
- * function stopCondition = Condition that, if true, will stop traversal (useful for performance)
137
- * function|string arbiter = If mutliple target routes found, this decides which to use (if any)
138
- *
139
198
  * @param {JourneyContext} context Journey context
140
- * @param {object} options Options
141
- * @returns {Array<object>} Routes that were traversed
199
+ * @param {PlanTraverseOptions} options Options
200
+ * @returns {PlanRoute[]} Routes that were traversed
142
201
  * @throws {TypeError} When context is not a JourneyContext
143
202
  */
144
- traverseRoutes(context: JourneyContext, options?: object): Array<object>;
203
+ traverseRoutes(context: JourneyContext, options?: PlanTraverseOptions): PlanRoute[];
145
204
  /**
146
205
  * Get raw graph data structure. This can be used with other libraries to
147
206
  * generate graph visualisations, for example.
@@ -151,4 +210,18 @@ export default class Plan {
151
210
  getGraphStructure(): Graph;
152
211
  #private;
153
212
  }
213
+ export type PlanRoute = import('../casa').PlanRoute;
214
+ export type PlanRouteCondition = import('../casa').PlanRouteCondition;
215
+ export type PlanTraverseOptions = import('../casa').PlanTraverseOptions;
216
+ export type PlanArbiter = import('../casa').PlanArbiter;
217
+ export type PlanConstructorOptions = {
218
+ /**
219
+ * Check page validity before conditions
220
+ */
221
+ validateBeforeRouteCondition?: boolean | undefined;
222
+ /**
223
+ * Arbitration mechanism
224
+ */
225
+ arbiter?: string | import("../casa").PlanArbiter | undefined;
226
+ };
154
227
  import JourneyContext from "./JourneyContext.js";
package/dist/lib/Plan.js CHANGED
@@ -19,13 +19,33 @@ const graphlib_1 = require("graphlib");
19
19
  const JourneyContext_js_1 = __importDefault(require("./JourneyContext.js"));
20
20
  const logger_js_1 = __importDefault(require("./logger.js"));
21
21
  const log = (0, logger_js_1.default)('lib:plan');
22
+ /**
23
+ * @access private
24
+ * @typedef {import('../casa').PlanRoute} PlanRoute
25
+ */
26
+ /**
27
+ * @access private
28
+ * @typedef {import('../casa').PlanRouteCondition} PlanRouteCondition
29
+ */
30
+ /**
31
+ * @access private
32
+ * @typedef {import('../casa').PlanTraverseOptions} PlanTraverseOptions
33
+ */
34
+ /**
35
+ * @access private
36
+ * @typedef {import('../casa').PlanArbiter} PlanArbiter
37
+ */
38
+ /**
39
+ * @typedef {object} PlanConstructorOptions
40
+ * @property {boolean} [validateBeforeRouteCondition=true] Check page validity before conditions
41
+ * @property {string|PlanArbiter} [arbiter=undefined] Arbitration mechanism
42
+ */
22
43
  /**
23
44
  * Will check if the source waypoint has specifically passed validation, i.e
24
45
  * there is a "null" validation entry for the route source.
25
46
  *
26
- * @param {object} r Route meta.
27
- * @param {JourneyContext} context Journey Context.
28
- * @returns {boolean} Condition result.
47
+ * @access private
48
+ * @type {PlanRouteCondition}
29
49
  */
30
50
  function defaultNextFollow(r, context) {
31
51
  const { validation: v = {} } = context.toObject();
@@ -35,14 +55,22 @@ function defaultNextFollow(r, context) {
35
55
  * Will check if the target waypoint (the one we're moving back to) has
36
56
  * specifically passed validation.
37
57
  *
38
- * @param {object} r Route meta.
39
- * @param {JourneyContext} context Journey context.
40
- * @returns {boolean} Condition result.
58
+ * @access private
59
+ * @type {PlanRouteCondition}
41
60
  */
42
61
  function defaultPrevFollow(r, context) {
43
62
  const { validation: v = {} } = context.toObject();
44
63
  return Object.prototype.hasOwnProperty.call(v, r.target) && v[r.target] === null;
45
64
  }
65
+ /**
66
+ * Validate a given waypoint ID.
67
+ *
68
+ * @access private
69
+ * @param {string} val Waypoint ID
70
+ * @returns {void}
71
+ * @throws {TypeError} If waypoint ID is not a string
72
+ * @throws {SyntaxError} If waypoint ID is incorrectly formatted
73
+ */
46
74
  function validateWaypointId(val) {
47
75
  if (typeof val !== 'string') {
48
76
  throw new TypeError(`Expected waypoint id to be a string, got ${typeof val}`);
@@ -51,6 +79,15 @@ function validateWaypointId(val) {
51
79
  throw new SyntaxError('url:// waypoints must include a trailing /');
52
80
  }
53
81
  }
82
+ /**
83
+ * Validate a given route name.
84
+ *
85
+ * @access private
86
+ * @param {string} val Route name
87
+ * @returns {string} The route name
88
+ * @throws {TypeError} If route name is not a string
89
+ * @throws {ReferenceError} If route name is neither "next" or "prev"
90
+ */
54
91
  function validateRouteName(val) {
55
92
  if (typeof val !== 'string') {
56
93
  throw new TypeError(`Expected route name to be a string, got ${typeof val}`);
@@ -60,6 +97,14 @@ function validateRouteName(val) {
60
97
  }
61
98
  return val;
62
99
  }
100
+ /**
101
+ * Validate a given route condition.
102
+ *
103
+ * @access private
104
+ * @param {PlanRouteCondition} val The condition function
105
+ * @returns {void}
106
+ * @throws {TypeError} If condition is not a string
107
+ */
63
108
  function validateRouteCondition(val) {
64
109
  if (!(val instanceof Function)) {
65
110
  throw new TypeError(`Expected route condition to be a function, got ${typeof val}`);
@@ -70,9 +115,10 @@ function validateRouteCondition(val) {
70
115
  * be used in userland. This is the object that will be passed into follow
71
116
  * functions too as the "route" parameter.
72
117
  *
118
+ * @access private
73
119
  * @param {object} dgraph Directed graph instance.
74
120
  * @param {object} edge Graph edge object.
75
- * @returns {object} Route.
121
+ * @returns {PlanRoute} Route.
76
122
  */
77
123
  const makeRouteObject = (dgraph, edge) => {
78
124
  const label = dgraph.edge(edge) || {};
@@ -86,16 +132,25 @@ const makeRouteObject = (dgraph, edge) => {
86
132
  };
87
133
  /**
88
134
  * Exit nodes begin with a protocol format, such as `url://`, `http://`, etc
135
+ *
136
+ * @access private
89
137
  */
90
138
  const reExitNodeProtocol = /^[a-z]+:\/\//i;
139
+ /**
140
+ * For storing private properties for each instance
141
+ *
142
+ * @access private
143
+ * @todo Use property private class properties.
144
+ */
91
145
  const priv = new WeakMap();
146
+ /**
147
+ * @memberof module:@dwp/govuk-casa
148
+ */
92
149
  class Plan {
93
150
  /**
94
151
  * Create a Plan.
95
152
  *
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
153
+ * @param {PlanConstructorOptions} opts Options
99
154
  */
100
155
  constructor(opts = {}) {
101
156
  /**
@@ -137,6 +192,11 @@ class Plan {
137
192
  static isExitNode(name) {
138
193
  return reExitNodeProtocol.test(name);
139
194
  }
195
+ /**
196
+ * Retrieve the options set on this Plan.
197
+ *
198
+ * @returns {PlanConstructorOptions} Options map
199
+ */
140
200
  getOptions() {
141
201
  return priv.get(this).options;
142
202
  }
@@ -152,7 +212,7 @@ class Plan {
152
212
  * Add one or more skippable waypoints.
153
213
  *
154
214
  * @param {...string} waypoints Waypoints
155
- * @returns {Plan}{ Chain}
215
+ * @returns {Plan} Chain
156
216
  */
157
217
  addSkippables(...waypoints) {
158
218
  __classPrivateFieldSet(this, _Plan_skippableWaypoints, [...__classPrivateFieldGet(this, _Plan_skippableWaypoints, "f"), ...waypoints], "f");
@@ -167,16 +227,40 @@ class Plan {
167
227
  isSkippable(waypoint) {
168
228
  return __classPrivateFieldGet(this, _Plan_skippableWaypoints, "f").indexOf(waypoint) > -1;
169
229
  }
230
+ /**
231
+ * Retrieve all waypoints in this Plan (order is arbitrary).
232
+ *
233
+ * @returns {string[]} List of waypoints
234
+ */
170
235
  getWaypoints() {
171
236
  return priv.get(this).dgraph.nodes();
172
237
  }
238
+ /**
239
+ * Determine if the given waypoint exists in this Plan.
240
+ *
241
+ * @param {string} waypoint Waypoint to search for
242
+ * @returns {boolean} Result
243
+ */
173
244
  containsWaypoint(waypoint) {
174
245
  return this.getWaypoints().includes(waypoint);
175
246
  }
247
+ /**
248
+ * Get all route information.
249
+ *
250
+ * @returns {PlanRoute[]} Routes
251
+ */
176
252
  getRoutes() {
177
253
  const self = priv.get(this);
178
254
  return self.dgraph.edges().map((edge) => makeRouteObject(self.dgraph, edge));
179
255
  }
256
+ /**
257
+ * Get the condition function for the given parameters.
258
+ *
259
+ * @param {string} src Source waypoint
260
+ * @param {string} tgt Target waypoint
261
+ * @param {string} name Route name
262
+ * @returns {PlanRouteCondition} Route condition function
263
+ */
180
264
  getRouteCondition(src, tgt, name) {
181
265
  return priv.get(this).follows[validateRouteName(name)][`${src}/${tgt}`];
182
266
  }
@@ -185,8 +269,8 @@ class Plan {
185
269
  * optional target waypoint.
186
270
  *
187
271
  * @param {string} src Source waypoint.
188
- * @param {string} tgt Target waypoint (optional).
189
- * @returns {Array<object>} Route objects found.
272
+ * @param {string} [tgt] Target waypoint.
273
+ * @returns {PlanRoute[]} Route objects found.
190
274
  */
191
275
  getOutwardRoutes(src, tgt = null) {
192
276
  const self = priv.get(this);
@@ -197,12 +281,19 @@ class Plan {
197
281
  * optional target waypoint, matching the "prev" name.
198
282
  *
199
283
  * @param {string} src Source waypoint.
200
- * @param {string} tgt Target waypoint (optional).
201
- * @returns {Array<object>} Route objects found.
284
+ * @param {string} [tgt] Target waypoint.
285
+ * @returns {PlanRoute[]} Route objects found.
202
286
  */
203
287
  getPrevOutwardRoutes(src, tgt = null) {
204
288
  return this.getOutwardRoutes(src, tgt).filter((r) => r.name === 'prev');
205
289
  }
290
+ /**
291
+ * Add a sequence of waypoints that will follow on from each other, with no
292
+ * routing logic between them.
293
+ *
294
+ * @param {...string} waypoints Waypoints to add
295
+ * @returns {void}
296
+ */
206
297
  addSequence(...waypoints) {
207
298
  // Setup simple double routes (next/prev) between all waypoints in this list
208
299
  for (let i = 0, l = waypoints.length - 1; i < l; i += 1) {
@@ -211,21 +302,37 @@ class Plan {
211
302
  this.setRoute(waypoints[i], waypoints[i + 1]);
212
303
  }
213
304
  }
305
+ /**
306
+ * Create a new directed route between two waypoints, labelled as "next".
307
+ *
308
+ * @param {string} src Source waypoint
309
+ * @param {string} tgt Target waypoint
310
+ * @param {PlanRouteCondition} follow Route condition function
311
+ * @returns {Plan} Chain
312
+ */
214
313
  setNextRoute(src, tgt, follow) {
215
314
  return this.setNamedRoute(src, tgt, 'next', follow);
216
315
  }
316
+ /**
317
+ * Create a new directed route between two waypoints, labelled as "prev".
318
+ *
319
+ * @param {string} src Source waypoint
320
+ * @param {string} tgt Target waypoint
321
+ * @param {PlanRouteCondition} follow Route condition function
322
+ * @returns {Plan} Chain
323
+ */
217
324
  setPrevRoute(src, tgt, follow) {
218
325
  return this.setNamedRoute(src, tgt, 'prev', follow);
219
326
  }
220
327
  /**
221
328
  * Adds both a "next" and "prev" route between the two waypoints.
222
329
  *
223
- * By default, the "prev" route will use the same "follow" test as the "next"
224
- * route. This makes sense in that in order to get the target, the test must
225
- * have been true, and so to reverse the direction we also need that same test
226
- * to be true.
330
+ * By default, the "prev" route will use the same "follow" condition as the
331
+ * "next" route. This makes sense in that in order to get to the target, the
332
+ * condition must be true, and so to reverse the direction we also need that
333
+ * same condition to be true.
227
334
  *
228
- * However, if the condition function uses the `source`/`target`
335
+ * However, if the condition function uses the `source`/`target` property
229
336
  * of the route in some way, then we must reverse these before passing to the
230
337
  * condition on the "prev" route because `source` in the condition will almost
231
338
  * certainly be referring to the source of the "next" route.
@@ -235,9 +342,9 @@ class Plan {
235
342
  *
236
343
  * @param {string} src Source waypoint.
237
344
  * @param {string} tgt Target waypoint.
238
- * @param {Function} followNext Follow test function.
239
- * @param {Function} followPrev Follow test function.
240
- * @returns {Plan} Self.
345
+ * @param {PlanRouteCondition} [followNext] Follow test function.
346
+ * @param {PlanRouteCondition} [followPrev] Follow test function.
347
+ * @returns {Plan} Chain
241
348
  */
242
349
  setRoute(src, tgt, followNext = undefined, followPrev = undefined) {
243
350
  this.setNamedRoute(src, tgt, 'next', followNext);
@@ -267,7 +374,7 @@ class Plan {
267
374
  * @param {string} src Source waypoint.
268
375
  * @param {string} tgt Target waypoint.
269
376
  * @param {string} name Name of the route (must be unique for this waypoint pairing).
270
- * @param {Function} follow Test function to determine if route can be followed.
377
+ * @param {PlanRouteCondition} follow Test function to determine if route can be followed.
271
378
  * @returns {Plan} Chain
272
379
  * @throws {Error} If attempting to create a "next" route from an exit node
273
380
  */
@@ -321,16 +428,32 @@ class Plan {
321
428
  * This is a convenience method for traversing all "next" routes, and returning
322
429
  * the IDs of all waypoints visited along the way.
323
430
  *
324
- * @param {JourneyContext} context Journey Context.
325
- * @param {object} options Options.
326
- * @returns {Array<string>} List of traversed waypoints.
431
+ * @param {JourneyContext} context Journey Context
432
+ * @param {PlanTraverseOptions} options Options
433
+ * @returns {string[]} List of traversed waypoints
327
434
  */
328
435
  traverse(context, options = {}) {
329
436
  return this.traverseNextRoutes(context, options).map((e) => e.source);
330
437
  }
438
+ /**
439
+ * Traverse the Plan by following all "next" routes, and returning the IDs of
440
+ * all waypoints visited along the way.
441
+ *
442
+ * @param {JourneyContext} context Journey Context
443
+ * @param {PlanTraverseOptions} options Options
444
+ * @returns {PlanRoute[]} List of traversed waypoints
445
+ */
331
446
  traverseNextRoutes(context, options = {}) {
332
447
  return this.traverseRoutes(context, Object.assign(Object.assign({}, options), { routeName: 'next' }));
333
448
  }
449
+ /**
450
+ * Traverse the Plan by following all "prev" routes, and returning the IDs of
451
+ * all waypoints visited along the way.
452
+ *
453
+ * @param {JourneyContext} context Journey Context
454
+ * @param {PlanTraverseOptions} options Options
455
+ * @returns {PlanRoute[]} List of traversed waypoints
456
+ */
334
457
  traversePrevRoutes(context, options = {}) {
335
458
  return this.traverseRoutes(context, Object.assign(Object.assign({}, options), { routeName: 'prev' }));
336
459
  }
@@ -344,16 +467,9 @@ class Plan {
344
467
  * If a cyclical set of routes are encountered, traversal will stop after
345
468
  * reaching the first repeated waypoint.
346
469
  *
347
- * Options:
348
- * string startWaypoint = Waypoint from which to start traversal
349
- * string routeName = Follow routes matching this name (next | prev)
350
- * Map history = Used to detect loops in traversal (internal use)
351
- * function stopCondition = Condition that, if true, will stop traversal (useful for performance)
352
- * function|string arbiter = If mutliple target routes found, this decides which to use (if any)
353
- *
354
470
  * @param {JourneyContext} context Journey context
355
- * @param {object} options Options
356
- * @returns {Array<object>} Routes that were traversed
471
+ * @param {PlanTraverseOptions} options Options
472
+ * @returns {PlanRoute[]} Routes that were traversed
357
473
  * @throws {TypeError} When context is not a JourneyContext
358
474
  */
359
475
  traverseRoutes(context, options = {}) {
@@ -361,6 +477,7 @@ class Plan {
361
477
  throw new TypeError(`Expected context to be an instance of JourneyContext, got ${typeof context}`);
362
478
  }
363
479
  const self = priv.get(this);
480
+ /** @type {PlanTraverseOptions} */
364
481
  const { startWaypoint = this.getWaypoints()[0], stopCondition = () => (false), arbiter = self.options.arbiter, routeName, } = options;
365
482
  if (!self.dgraph.hasNode(startWaypoint)) {
366
483
  throw new ReferenceError(`Plan does not contain waypoint '${startWaypoint}'`);
@@ -398,7 +515,14 @@ class Plan {
398
515
  }
399
516
  else if (arbiter instanceof Function) {
400
517
  log.debug('Using custom arbitration process');
401
- target = arbiter(target, Object.assign({ context }, options));
518
+ // Convert to routeObject and back to edge object so that only the
519
+ // routeObject is used in the public API
520
+ target = arbiter({
521
+ targets: target.map((t) => makeRouteObject(self.dgraph, t)),
522
+ journeyContext: context,
523
+ travereOptions: options,
524
+ });
525
+ target = target.map((r) => ({ v: r.source, w: r.target, name: r.name }));
402
526
  }
403
527
  else {
404
528
  log.warn('Unable to arbitrate');