@dwp/govuk-casa 8.0.0-alpha2 → 8.0.0-beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/casa.d.ts +2 -1
- package/dist/casa.js +3 -1
- package/dist/lib/CasaTemplateLoader.d.ts +6 -2
- package/dist/lib/CasaTemplateLoader.js +4 -1
- package/dist/lib/JourneyContext.d.ts +37 -6
- package/dist/lib/JourneyContext.js +21 -6
- package/dist/lib/MutableRouter.js +3 -1
- package/dist/lib/Plan.d.ts +37 -4
- package/dist/lib/Plan.js +63 -6
- package/dist/lib/ValidationError.d.ts +6 -2
- package/dist/lib/ValidationError.js +3 -0
- package/dist/lib/ValidatorFactory.d.ts +72 -19
- package/dist/lib/ValidatorFactory.js +33 -20
- package/dist/lib/configuration-ingestor.d.ts +262 -0
- package/dist/lib/configuration-ingestor.js +490 -0
- package/dist/lib/configure.d.ts +26 -140
- package/dist/lib/configure.js +16 -43
- package/dist/lib/dirname.d.cts +2 -0
- package/dist/lib/end-session.d.ts +2 -1
- package/dist/lib/end-session.js +24 -7
- package/dist/lib/field.d.ts +38 -45
- package/dist/lib/field.js +56 -34
- package/dist/lib/index.d.ts +14 -0
- package/dist/lib/index.js +54 -0
- package/dist/lib/logger.d.ts +2 -1
- package/dist/lib/logger.js +2 -3
- package/dist/lib/utils.d.ts +18 -2
- package/dist/lib/utils.js +54 -2
- package/dist/lib/waypoint-url.d.ts +2 -1
- package/dist/lib/waypoint-url.js +3 -0
- package/dist/middleware/body-parser.js +2 -2
- package/dist/middleware/data.d.ts +1 -2
- package/dist/middleware/data.js +4 -8
- package/dist/middleware/dirname.d.cts +2 -0
- package/dist/middleware/gather-fields.d.ts +2 -1
- package/dist/middleware/gather-fields.js +3 -0
- package/dist/middleware/post.js +6 -6
- package/dist/middleware/sanitise-fields.js +4 -4
- package/dist/middleware/session.d.ts +2 -1
- package/dist/middleware/session.js +2 -2
- package/dist/middleware/steer-journey.d.ts +2 -1
- package/dist/middleware/steer-journey.js +3 -0
- package/dist/routes/ancillary.d.ts +8 -1
- package/dist/routes/ancillary.js +7 -0
- package/dist/routes/dirname.d.cts +2 -0
- package/dist/routes/journey.js +9 -2
- package/dist/routes/static.js +4 -3
- package/package.json +27 -17
- package/views/casa/layouts/main.njk +2 -2
package/dist/casa.d.ts
CHANGED
|
@@ -3,8 +3,9 @@ import validators from "./lib/validators/index.js";
|
|
|
3
3
|
import field from "./lib/field.js";
|
|
4
4
|
import Plan from "./lib/Plan.js";
|
|
5
5
|
import JourneyContext from "./lib/JourneyContext.js";
|
|
6
|
+
import ValidatorFactory from "./lib/ValidatorFactory.js";
|
|
6
7
|
import ValidationError from "./lib/ValidationError.js";
|
|
7
8
|
import waypointUrl from "./lib/waypoint-url.js";
|
|
8
9
|
import endSession from "./lib/end-session.js";
|
|
9
10
|
import * as nunjucksFilters from "./lib/nunjucks-filters.js";
|
|
10
|
-
export { configure, validators, field, Plan, JourneyContext, ValidationError, waypointUrl, endSession, nunjucksFilters };
|
|
11
|
+
export { configure, validators, field, Plan, JourneyContext, ValidatorFactory, ValidationError, waypointUrl, endSession, nunjucksFilters };
|
package/dist/casa.js
CHANGED
|
@@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
22
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
23
|
};
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.nunjucksFilters = exports.endSession = exports.waypointUrl = exports.ValidationError = exports.JourneyContext = exports.Plan = exports.field = exports.validators = exports.configure = void 0;
|
|
25
|
+
exports.nunjucksFilters = exports.endSession = exports.waypointUrl = exports.ValidationError = exports.ValidatorFactory = exports.JourneyContext = exports.Plan = exports.field = exports.validators = exports.configure = void 0;
|
|
26
26
|
// NOTE: Any changes made here must be reflected in `scripts/esm-wrapper.js`
|
|
27
27
|
const configure_js_1 = __importDefault(require("./lib/configure.js"));
|
|
28
28
|
exports.configure = configure_js_1.default;
|
|
@@ -34,6 +34,8 @@ const Plan_js_1 = __importDefault(require("./lib/Plan.js"));
|
|
|
34
34
|
exports.Plan = Plan_js_1.default;
|
|
35
35
|
const JourneyContext_js_1 = __importDefault(require("./lib/JourneyContext.js"));
|
|
36
36
|
exports.JourneyContext = JourneyContext_js_1.default;
|
|
37
|
+
const ValidatorFactory_js_1 = __importDefault(require("./lib/ValidatorFactory.js"));
|
|
38
|
+
exports.ValidatorFactory = ValidatorFactory_js_1.default;
|
|
37
39
|
const ValidationError_js_1 = __importDefault(require("./lib/ValidationError.js"));
|
|
38
40
|
exports.ValidationError = ValidationError_js_1.default;
|
|
39
41
|
const waypoint_url_js_1 = __importDefault(require("./lib/waypoint-url.js"));
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('nunjucks').FileSystemLoaderOptions} FileSystemLoaderOptions
|
|
3
|
+
*/
|
|
1
4
|
/**
|
|
2
5
|
* @callback BlockModifier
|
|
3
6
|
* @param {string} templateName Path to the template being modified
|
|
@@ -8,9 +11,9 @@ export default class CasaTemplateLoader extends FileSystemLoader {
|
|
|
8
11
|
* Constructor.
|
|
9
12
|
*
|
|
10
13
|
* @param {string[]} searchPaths Template directories
|
|
11
|
-
* @param {
|
|
14
|
+
* @param {FileSystemLoaderOptions} opts Loader options
|
|
12
15
|
*/
|
|
13
|
-
constructor(searchPaths: string[], opts:
|
|
16
|
+
constructor(searchPaths: string[], opts: FileSystemLoaderOptions);
|
|
14
17
|
/**
|
|
15
18
|
* Add a modification function to the loader.
|
|
16
19
|
*
|
|
@@ -21,5 +24,6 @@ export default class CasaTemplateLoader extends FileSystemLoader {
|
|
|
21
24
|
modifyBlock(block: string, modifier: BlockModifier): void;
|
|
22
25
|
#private;
|
|
23
26
|
}
|
|
27
|
+
export type FileSystemLoaderOptions = import('nunjucks').FileSystemLoaderOptions;
|
|
24
28
|
export type BlockModifier = (templateName: string) => string;
|
|
25
29
|
import { FileSystemLoader } from "nunjucks";
|
|
@@ -13,6 +13,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
var _CasaTemplateLoader_instances, _CasaTemplateLoader_blockModifiers, _CasaTemplateLoader_applyBlockModifiers;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
const nunjucks_1 = require("nunjucks");
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {import('nunjucks').FileSystemLoaderOptions} FileSystemLoaderOptions
|
|
18
|
+
*/
|
|
16
19
|
/**
|
|
17
20
|
* @callback BlockModifier
|
|
18
21
|
* @param {string} templateName Path to the template being modified
|
|
@@ -23,7 +26,7 @@ class CasaTemplateLoader extends nunjucks_1.FileSystemLoader {
|
|
|
23
26
|
* Constructor.
|
|
24
27
|
*
|
|
25
28
|
* @param {string[]} searchPaths Template directories
|
|
26
|
-
* @param {
|
|
29
|
+
* @param {FileSystemLoaderOptions} opts Loader options
|
|
27
30
|
*/
|
|
28
31
|
constructor(searchPaths, opts) {
|
|
29
32
|
super(searchPaths, opts);
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('./configuration-ingestor').Page} Page
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* @callback ContextEventHandler
|
|
6
|
+
* @param {JourneyContext} journeyContext Context including changes
|
|
7
|
+
* @param {JourneyContext} previousContext Context prior to changes
|
|
8
|
+
* @returns {void}
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {object} ContextEvent
|
|
12
|
+
* @property {string} waypoint Waypoint to watch for changes
|
|
13
|
+
* @property {string} [field] Field to watch for changes
|
|
14
|
+
* @property {ContextEventHandler} handler Handler to invoke when change happens
|
|
15
|
+
*/
|
|
1
16
|
export default class JourneyContext {
|
|
2
17
|
static DEFAULT_CONTEXT_ID: string;
|
|
3
18
|
/**
|
|
@@ -133,11 +148,11 @@ export default class JourneyContext {
|
|
|
133
148
|
/**
|
|
134
149
|
* Get data context for a specific a specific page.
|
|
135
150
|
*
|
|
136
|
-
* @param {string |
|
|
151
|
+
* @param {string | Page} page Page waypoint ID, or Page object.
|
|
137
152
|
* @returns {object} Page data.
|
|
138
153
|
* @throws {TypeError} When page is invalid.
|
|
139
154
|
*/
|
|
140
|
-
getDataForPage(page: string |
|
|
155
|
+
getDataForPage(page: string | Page): object;
|
|
141
156
|
getData(): object;
|
|
142
157
|
/**
|
|
143
158
|
* Overwrite the data context with a new object.
|
|
@@ -150,16 +165,16 @@ export default class JourneyContext {
|
|
|
150
165
|
* Write field form data from a page HTML form, into the `data` model.
|
|
151
166
|
*
|
|
152
167
|
* By default this will store the data as-is, keyed against the page's
|
|
153
|
-
* waypoint ID. However, when passing a `
|
|
168
|
+
* waypoint ID. However, when passing a `Page` instance, its
|
|
154
169
|
* `fieldWriter()` method will be called to transform the provided formData
|
|
155
170
|
* before storing in `data`
|
|
156
171
|
*
|
|
157
|
-
* @param {string |
|
|
172
|
+
* @param {string | Page} page Page waypoint ID, or Page object
|
|
158
173
|
* @param {object} webFormData Data to overwrite with
|
|
159
174
|
* @returns {JourneyContext} Chain
|
|
160
175
|
* @throws {TypeError} When page is invalid.
|
|
161
176
|
*/
|
|
162
|
-
setDataForPage(page: string |
|
|
177
|
+
setDataForPage(page: string | Page, webFormData: object): JourneyContext;
|
|
163
178
|
/**
|
|
164
179
|
* Return validation errors for all pages.
|
|
165
180
|
*
|
|
@@ -251,7 +266,7 @@ export default class JourneyContext {
|
|
|
251
266
|
* @param {ContextEvent[]} events Event listeners
|
|
252
267
|
* @returns {JourneyContext} Chain
|
|
253
268
|
*/
|
|
254
|
-
addEventListeners(events:
|
|
269
|
+
addEventListeners(events: ContextEvent[]): JourneyContext;
|
|
255
270
|
applyEventListeners({ event }: {
|
|
256
271
|
event: any;
|
|
257
272
|
}): JourneyContext;
|
|
@@ -263,4 +278,20 @@ export default class JourneyContext {
|
|
|
263
278
|
isDefault(): boolean;
|
|
264
279
|
#private;
|
|
265
280
|
}
|
|
281
|
+
export type Page = import('./configuration-ingestor').Page;
|
|
282
|
+
export type ContextEventHandler = (journeyContext: JourneyContext, previousContext: JourneyContext) => void;
|
|
283
|
+
export type ContextEvent = {
|
|
284
|
+
/**
|
|
285
|
+
* Waypoint to watch for changes
|
|
286
|
+
*/
|
|
287
|
+
waypoint: string;
|
|
288
|
+
/**
|
|
289
|
+
* Field to watch for changes
|
|
290
|
+
*/
|
|
291
|
+
field?: string | undefined;
|
|
292
|
+
/**
|
|
293
|
+
* Handler to invoke when change happens
|
|
294
|
+
*/
|
|
295
|
+
handler: ContextEventHandler;
|
|
296
|
+
};
|
|
266
297
|
import ValidationError from "./ValidationError.js";
|
|
@@ -40,6 +40,21 @@ const ValidationError_js_1 = __importDefault(require("./ValidationError.js"));
|
|
|
40
40
|
const logger_js_1 = __importDefault(require("./logger.js"));
|
|
41
41
|
const { cloneDeep, isPlainObject, isObject, has, isEqual, } = lodash_1.default; // CommonJS
|
|
42
42
|
const log = (0, logger_js_1.default)('class:journey-context');
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {import('./configuration-ingestor').Page} Page
|
|
45
|
+
*/
|
|
46
|
+
/**
|
|
47
|
+
* @callback ContextEventHandler
|
|
48
|
+
* @param {JourneyContext} journeyContext Context including changes
|
|
49
|
+
* @param {JourneyContext} previousContext Context prior to changes
|
|
50
|
+
* @returns {void}
|
|
51
|
+
*/
|
|
52
|
+
/**
|
|
53
|
+
* @typedef {object} ContextEvent
|
|
54
|
+
* @property {string} waypoint Waypoint to watch for changes
|
|
55
|
+
* @property {string} [field] Field to watch for changes
|
|
56
|
+
* @property {ContextEventHandler} handler Handler to invoke when change happens
|
|
57
|
+
*/
|
|
43
58
|
class JourneyContext {
|
|
44
59
|
/**
|
|
45
60
|
* Constructor.
|
|
@@ -123,7 +138,7 @@ class JourneyContext {
|
|
|
123
138
|
/**
|
|
124
139
|
* Get data context for a specific a specific page.
|
|
125
140
|
*
|
|
126
|
-
* @param {string |
|
|
141
|
+
* @param {string | Page} page Page waypoint ID, or Page object.
|
|
127
142
|
* @returns {object} Page data.
|
|
128
143
|
* @throws {TypeError} When page is invalid.
|
|
129
144
|
*/
|
|
@@ -153,11 +168,11 @@ class JourneyContext {
|
|
|
153
168
|
* Write field form data from a page HTML form, into the `data` model.
|
|
154
169
|
*
|
|
155
170
|
* By default this will store the data as-is, keyed against the page's
|
|
156
|
-
* waypoint ID. However, when passing a `
|
|
171
|
+
* waypoint ID. However, when passing a `Page` instance, its
|
|
157
172
|
* `fieldWriter()` method will be called to transform the provided formData
|
|
158
173
|
* before storing in `data`
|
|
159
174
|
*
|
|
160
|
-
* @param {string |
|
|
175
|
+
* @param {string | Page} page Page waypoint ID, or Page object
|
|
161
176
|
* @param {object} webFormData Data to overwrite with
|
|
162
177
|
* @returns {JourneyContext} Chain
|
|
163
178
|
* @throws {TypeError} When page is invalid.
|
|
@@ -325,7 +340,7 @@ class JourneyContext {
|
|
|
325
340
|
return this;
|
|
326
341
|
}
|
|
327
342
|
applyEventListeners({ event }) {
|
|
328
|
-
var _a, _b, _c, _d, _e, _f;
|
|
343
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
329
344
|
if (!__classPrivateFieldGet(this, _JourneyContext_eventListeners, "f").length) {
|
|
330
345
|
return this;
|
|
331
346
|
}
|
|
@@ -341,11 +356,11 @@ class JourneyContext {
|
|
|
341
356
|
}
|
|
342
357
|
else if (waypoint && !field) {
|
|
343
358
|
logMessage = `Calling waypoint-specific event handler on "${waypoint}"`;
|
|
344
|
-
runHandler =
|
|
359
|
+
runHandler = ((_a = previousContext.data) === null || _a === void 0 ? void 0 : _a[waypoint]) !== undefined && !isEqual((_b = this.data) === null || _b === void 0 ? void 0 : _b[waypoint], (_c = previousContext.data) === null || _c === void 0 ? void 0 : _c[waypoint]);
|
|
345
360
|
}
|
|
346
361
|
else if (waypoint && field) {
|
|
347
362
|
logMessage = `Calling field-specific event handler on "${waypoint} : ${field}"`;
|
|
348
|
-
runHandler = !isEqual((
|
|
363
|
+
runHandler = ((_e = (_d = previousContext.data) === null || _d === void 0 ? void 0 : _d[waypoint]) === null || _e === void 0 ? void 0 : _e[field]) !== undefined && !isEqual((_g = (_f = this.data) === null || _f === void 0 ? void 0 : _f[waypoint]) === null || _g === void 0 ? void 0 : _g[field], (_j = (_h = previousContext.data) === null || _h === void 0 ? void 0 : _h[waypoint]) === null || _j === void 0 ? void 0 : _j[field]);
|
|
349
364
|
}
|
|
350
365
|
if (runHandler) {
|
|
351
366
|
log.trace(logMessage);
|
|
@@ -264,12 +264,14 @@ _MutableRouter_stack = new WeakMap(), _MutableRouter_router = new WeakMap(), _Mu
|
|
|
264
264
|
if (__classPrivateFieldGet(this, _MutableRouter_sealed, "f")) {
|
|
265
265
|
throw new Error('Cannot alter middleware in a sealed mutable router');
|
|
266
266
|
}
|
|
267
|
-
const
|
|
267
|
+
const finder = (command) => `${command.method}|${command.path}` === `${method}|${path}`;
|
|
268
|
+
const index = __classPrivateFieldGet(this, _MutableRouter_stack, "f").findIndex(finder);
|
|
268
269
|
if (index > -1) {
|
|
269
270
|
__classPrivateFieldGet(this, _MutableRouter_stack, "f").splice(index, 1, {
|
|
270
271
|
method,
|
|
271
272
|
path,
|
|
272
273
|
args: [path, ...callbacks],
|
|
273
274
|
});
|
|
275
|
+
__classPrivateFieldSet(this, _MutableRouter_stack, __classPrivateFieldGet(this, _MutableRouter_stack, "f").filter((command, idx) => idx <= index || !finder(command)), "f");
|
|
274
276
|
}
|
|
275
277
|
};
|
package/dist/lib/Plan.d.ts
CHANGED
|
@@ -1,12 +1,44 @@
|
|
|
1
1
|
export default class Plan {
|
|
2
|
-
|
|
2
|
+
/**
|
|
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;
|
|
3
10
|
/**
|
|
4
11
|
* Create a Plan.
|
|
5
12
|
*
|
|
6
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
|
|
7
16
|
*/
|
|
8
|
-
constructor(opts?:
|
|
17
|
+
constructor(opts?: {
|
|
18
|
+
validateBeforeRouteCondition?: boolean | undefined;
|
|
19
|
+
arbiter?: string | Function | undefined;
|
|
20
|
+
});
|
|
9
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;
|
|
10
42
|
getWaypoints(): any;
|
|
11
43
|
containsWaypoint(waypoint: any): any;
|
|
12
44
|
getRoutes(): any;
|
|
@@ -114,8 +146,9 @@ export default class Plan {
|
|
|
114
146
|
* Get raw graph data structure. This can be used with other libraries to
|
|
115
147
|
* generate graph visualisations, for example.
|
|
116
148
|
*
|
|
117
|
-
* @returns {
|
|
149
|
+
* @returns {Graph} Graph data structure.
|
|
118
150
|
*/
|
|
119
|
-
getGraphStructure():
|
|
151
|
+
getGraphStructure(): Graph;
|
|
152
|
+
#private;
|
|
120
153
|
}
|
|
121
154
|
import JourneyContext from "./JourneyContext.js";
|
package/dist/lib/Plan.js
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
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"));
|
|
@@ -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') {
|
|
@@ -74,15 +89,18 @@ const makeRouteObject = (dgraph, edge) => {
|
|
|
74
89
|
const reExitNodeProtocol = /^[a-z]+:\/\//i;
|
|
75
90
|
const priv = new WeakMap();
|
|
76
91
|
class Plan {
|
|
77
|
-
static isExitNode(name) {
|
|
78
|
-
return reExitNodeProtocol.test(name);
|
|
79
|
-
}
|
|
80
92
|
/**
|
|
81
93
|
* Create a Plan.
|
|
82
94
|
*
|
|
83
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
|
|
84
98
|
*/
|
|
85
99
|
constructor(opts = {}) {
|
|
100
|
+
/**
|
|
101
|
+
* @type {string[]} These waypoints can be skipped
|
|
102
|
+
*/
|
|
103
|
+
_Plan_skippableWaypoints.set(this, void 0);
|
|
86
104
|
// This is our directed, multigraph representation
|
|
87
105
|
const dgraph = new graphlib_1.Graph({
|
|
88
106
|
directed: true,
|
|
@@ -106,10 +124,48 @@ class Plan {
|
|
|
106
124
|
},
|
|
107
125
|
options,
|
|
108
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);
|
|
109
138
|
}
|
|
110
139
|
getOptions() {
|
|
111
140
|
return priv.get(this).options;
|
|
112
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
|
+
}
|
|
113
169
|
getWaypoints() {
|
|
114
170
|
return priv.get(this).dgraph.nodes();
|
|
115
171
|
}
|
|
@@ -222,12 +278,12 @@ class Plan {
|
|
|
222
278
|
validateRouteCondition(follow);
|
|
223
279
|
}
|
|
224
280
|
// Get routing function name to label edge
|
|
225
|
-
const
|
|
281
|
+
const conditionName = follow && follow.name;
|
|
226
282
|
// Warn if we're overwriting an existing edge on the same name
|
|
227
283
|
if (self.dgraph.hasEdge(src, tgt, name)) {
|
|
228
284
|
log.warn('Setting a route that already exists (%s, %s, %s). Will be overridden', src, tgt, name);
|
|
229
285
|
}
|
|
230
|
-
self.dgraph.setEdge(src, tgt, {
|
|
286
|
+
self.dgraph.setEdge(src, tgt, { conditionName }, name);
|
|
231
287
|
// Determine which follow function to use
|
|
232
288
|
let followFunc;
|
|
233
289
|
if (follow) {
|
|
@@ -376,10 +432,11 @@ class Plan {
|
|
|
376
432
|
* Get raw graph data structure. This can be used with other libraries to
|
|
377
433
|
* generate graph visualisations, for example.
|
|
378
434
|
*
|
|
379
|
-
* @returns {
|
|
435
|
+
* @returns {Graph} Graph data structure.
|
|
380
436
|
*/
|
|
381
437
|
getGraphStructure() {
|
|
382
438
|
return priv.get(this).dgraph;
|
|
383
439
|
}
|
|
384
440
|
}
|
|
385
441
|
exports.default = Plan;
|
|
442
|
+
_Plan_skippableWaypoints = new WeakMap();
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('./ValidatorFactory').ValidateContext} ValidateContext
|
|
3
|
+
*/
|
|
1
4
|
export default class ValidationError {
|
|
2
5
|
/**
|
|
3
6
|
* Make a ValidationError instance from a primitive object (or a function that
|
|
@@ -61,10 +64,11 @@ export default class ValidationError {
|
|
|
61
64
|
* @param {ValidateContext} context See structure above
|
|
62
65
|
* @returns {ValidationError} Chain
|
|
63
66
|
*/
|
|
64
|
-
withContext(context:
|
|
67
|
+
withContext(context: ValidateContext): ValidationError;
|
|
65
68
|
variables: any;
|
|
66
|
-
field:
|
|
69
|
+
field: string | undefined;
|
|
67
70
|
fieldHref: string | undefined;
|
|
68
71
|
focusSuffix: any;
|
|
69
72
|
validator: any;
|
|
70
73
|
}
|
|
74
|
+
export type ValidateContext = import('./ValidatorFactory').ValidateContext;
|
|
@@ -6,6 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const lodash_1 = __importDefault(require("lodash"));
|
|
7
7
|
const { isPlainObject } = lodash_1.default; // CommonJS
|
|
8
8
|
const params = new WeakMap();
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {import('./ValidatorFactory').ValidateContext} ValidateContext
|
|
11
|
+
*/
|
|
9
12
|
class ValidationError {
|
|
10
13
|
/**
|
|
11
14
|
* Make a ValidationError instance from a primitive object (or a function that
|
|
@@ -1,30 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('./index').ProcessorFunction} ProcessorFunction
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import('./index').JourneyContext} JourneyContext
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {import('./index').ValidationError} ValidationError
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {object} Validator
|
|
12
|
+
* @property {ValidateFunction} validate Validation function
|
|
13
|
+
* @property {ProcessorFunction} sanitise Sanitise a given value prior to validation
|
|
14
|
+
* @property {object} config Configuration
|
|
15
|
+
* @property {string} name Validator name
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* @callback ValidateFunction
|
|
19
|
+
* @param {any} value
|
|
20
|
+
* @param {ValidateContext} context
|
|
21
|
+
* @returns {ValidationError[]}
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {object} ValidateContext Context passed to validate function
|
|
25
|
+
* @property {JourneyContext} journeyContext Journey context
|
|
26
|
+
* @property {string} waypoint Waypoint
|
|
27
|
+
* @property {string} fieldName Name of field being processed
|
|
28
|
+
*/
|
|
1
29
|
export default class ValidatorFactory {
|
|
2
30
|
/**
|
|
3
|
-
* This is a convenience method that will
|
|
4
|
-
*
|
|
5
|
-
* method. i.e.
|
|
31
|
+
* This is a convenience method that will return a consistently object
|
|
32
|
+
* structure containing validation and sanitisation methods.
|
|
6
33
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* (new MyValidator()).validate('value to validate')
|
|
10
|
-
*
|
|
11
|
-
* It also attaches the `sanitise()` method as a static property to that
|
|
12
|
-
* function.
|
|
13
|
-
*
|
|
14
|
-
* @param {object} config Validator config
|
|
15
|
-
* @returns {object} Validator object
|
|
34
|
+
* @param {object} config Validator config (custom to the validator being created)
|
|
35
|
+
* @returns {Validator} Validator object
|
|
16
36
|
* @throws {TypeError} When configurarion is invalid.
|
|
17
37
|
*/
|
|
18
|
-
static make(config?: object):
|
|
38
|
+
static make(config?: object): Validator;
|
|
19
39
|
static coerceToValidatorObject(input: any): any;
|
|
20
40
|
constructor(config?: {});
|
|
21
41
|
config: {};
|
|
22
|
-
/**
|
|
23
|
-
* Validate the field value.
|
|
24
|
-
*
|
|
25
|
-
* @param {any} fieldValue Field value
|
|
26
|
-
* @param {ValidateContext} context Validation context
|
|
27
|
-
*/
|
|
28
42
|
validate(fieldValue: any, context: any): void;
|
|
29
43
|
sanitise(fieldValue: any): any;
|
|
30
44
|
}
|
|
45
|
+
export type ProcessorFunction = import('./index').ProcessorFunction;
|
|
46
|
+
export type JourneyContext = import('./index').JourneyContext;
|
|
47
|
+
export type ValidationError = import('./index').ValidationError;
|
|
48
|
+
export type Validator = {
|
|
49
|
+
/**
|
|
50
|
+
* Validation function
|
|
51
|
+
*/
|
|
52
|
+
validate: ValidateFunction;
|
|
53
|
+
/**
|
|
54
|
+
* Sanitise a given value prior to validation
|
|
55
|
+
*/
|
|
56
|
+
sanitise: any;
|
|
57
|
+
/**
|
|
58
|
+
* Configuration
|
|
59
|
+
*/
|
|
60
|
+
config: object;
|
|
61
|
+
/**
|
|
62
|
+
* Validator name
|
|
63
|
+
*/
|
|
64
|
+
name: string;
|
|
65
|
+
};
|
|
66
|
+
export type ValidateFunction = (value: any, context: ValidateContext) => ValidationError[];
|
|
67
|
+
/**
|
|
68
|
+
* Context passed to validate function
|
|
69
|
+
*/
|
|
70
|
+
export type ValidateContext = {
|
|
71
|
+
/**
|
|
72
|
+
* Journey context
|
|
73
|
+
*/
|
|
74
|
+
journeyContext: JourneyContext;
|
|
75
|
+
/**
|
|
76
|
+
* Waypoint
|
|
77
|
+
*/
|
|
78
|
+
waypoint: string;
|
|
79
|
+
/**
|
|
80
|
+
* Name of field being processed
|
|
81
|
+
*/
|
|
82
|
+
fieldName: string;
|
|
83
|
+
};
|
|
@@ -4,24 +4,43 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
/* eslint-disable class-methods-use-this */
|
|
7
|
-
// const { isPlainObject } = require('../Util.js');
|
|
8
7
|
const lodash_1 = __importDefault(require("lodash"));
|
|
9
8
|
const { isPlainObject } = lodash_1.default; // CommonJS
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {import('./index').ProcessorFunction} ProcessorFunction
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {import('./index').JourneyContext} JourneyContext
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {import('./index').ValidationError} ValidationError
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {object} Validator
|
|
20
|
+
* @property {ValidateFunction} validate Validation function
|
|
21
|
+
* @property {ProcessorFunction} sanitise Sanitise a given value prior to validation
|
|
22
|
+
* @property {object} config Configuration
|
|
23
|
+
* @property {string} name Validator name
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* @callback ValidateFunction
|
|
27
|
+
* @param {any} value
|
|
28
|
+
* @param {ValidateContext} context
|
|
29
|
+
* @returns {ValidationError[]}
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* @typedef {object} ValidateContext Context passed to validate function
|
|
33
|
+
* @property {JourneyContext} journeyContext Journey context
|
|
34
|
+
* @property {string} waypoint Waypoint
|
|
35
|
+
* @property {string} fieldName Name of field being processed
|
|
36
|
+
*/
|
|
10
37
|
class ValidatorFactory {
|
|
11
38
|
/**
|
|
12
|
-
* This is a convenience method that will
|
|
13
|
-
*
|
|
14
|
-
* method. i.e.
|
|
39
|
+
* This is a convenience method that will return a consistently object
|
|
40
|
+
* structure containing validation and sanitisation methods.
|
|
15
41
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* (new MyValidator()).validate('value to validate')
|
|
19
|
-
*
|
|
20
|
-
* It also attaches the `sanitise()` method as a static property to that
|
|
21
|
-
* function.
|
|
22
|
-
*
|
|
23
|
-
* @param {object} config Validator config
|
|
24
|
-
* @returns {object} Validator object
|
|
42
|
+
* @param {object} config Validator config (custom to the validator being created)
|
|
43
|
+
* @returns {Validator} Validator object
|
|
25
44
|
* @throws {TypeError} When configurarion is invalid.
|
|
26
45
|
*/
|
|
27
46
|
static make(config = {}) {
|
|
@@ -31,7 +50,7 @@ class ValidatorFactory {
|
|
|
31
50
|
const validator = Reflect.construct(this, [config]);
|
|
32
51
|
/* eslint-disable-next-line sonarjs/prefer-object-literal */
|
|
33
52
|
const instance = {};
|
|
34
|
-
instance.name = validator.name ||
|
|
53
|
+
instance.name = validator.name || 'unknown';
|
|
35
54
|
instance.config = config;
|
|
36
55
|
instance.validate = validator.validate.bind(instance);
|
|
37
56
|
instance.sanitise = validator.sanitise.bind(instance);
|
|
@@ -75,12 +94,6 @@ class ValidatorFactory {
|
|
|
75
94
|
}
|
|
76
95
|
this.config = config;
|
|
77
96
|
}
|
|
78
|
-
/**
|
|
79
|
-
* Validate the field value.
|
|
80
|
-
*
|
|
81
|
-
* @param {any} fieldValue Field value
|
|
82
|
-
* @param {ValidateContext} context Validation context
|
|
83
|
-
*/
|
|
84
97
|
/* eslint-disable-next-line no-unused-vars */
|
|
85
98
|
validate(fieldValue, context) {
|
|
86
99
|
throw new Error('validate() method has not been implemented');
|