@dwp/govuk-casa 8.0.0-alpha2 → 8.0.1

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 (66) hide show
  1. package/CHANGELOG.md +14 -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 +4 -2
  8. package/dist/lib/CasaTemplateLoader.js +26 -4
  9. package/dist/lib/JourneyContext.d.ts +38 -6
  10. package/dist/lib/JourneyContext.js +58 -17
  11. package/dist/lib/MutableRouter.js +6 -2
  12. package/dist/lib/Plan.d.ts +37 -4
  13. package/dist/lib/Plan.js +75 -11
  14. package/dist/lib/ValidationError.d.ts +6 -2
  15. package/dist/lib/ValidationError.js +7 -0
  16. package/dist/lib/ValidatorFactory.d.ts +72 -19
  17. package/dist/lib/ValidatorFactory.js +33 -20
  18. package/dist/lib/configuration-ingestor.d.ts +262 -0
  19. package/dist/lib/configuration-ingestor.js +464 -0
  20. package/dist/lib/configure.d.ts +26 -140
  21. package/dist/lib/configure.js +17 -45
  22. package/dist/lib/dirname.cjs +1 -1
  23. package/dist/lib/dirname.d.cts +2 -0
  24. package/dist/lib/end-session.d.ts +2 -1
  25. package/dist/lib/end-session.js +27 -7
  26. package/dist/lib/field.d.ts +39 -46
  27. package/dist/lib/field.js +75 -36
  28. package/dist/lib/index.d.ts +14 -0
  29. package/dist/lib/index.js +54 -0
  30. package/dist/lib/logger.d.ts +2 -1
  31. package/dist/lib/logger.js +3 -4
  32. package/dist/lib/nunjucks-filters.js +8 -0
  33. package/dist/lib/utils.d.ts +18 -2
  34. package/dist/lib/utils.js +56 -2
  35. package/dist/lib/validators/inArray.js +1 -1
  36. package/dist/lib/validators/index.js +0 -22
  37. package/dist/lib/validators/postalAddressObject.js +6 -2
  38. package/dist/lib/waypoint-url.d.ts +2 -1
  39. package/dist/lib/waypoint-url.js +3 -0
  40. package/dist/middleware/body-parser.d.ts +1 -0
  41. package/dist/middleware/body-parser.js +18 -9
  42. package/dist/middleware/data.d.ts +1 -2
  43. package/dist/middleware/data.js +9 -9
  44. package/dist/middleware/dirname.cjs +1 -1
  45. package/dist/middleware/dirname.d.cts +2 -0
  46. package/dist/middleware/gather-fields.d.ts +2 -1
  47. package/dist/middleware/gather-fields.js +6 -5
  48. package/dist/middleware/i18n.js +5 -1
  49. package/dist/middleware/post.js +6 -6
  50. package/dist/middleware/progress-journey.js +1 -1
  51. package/dist/middleware/sanitise-fields.js +9 -9
  52. package/dist/middleware/session.d.ts +2 -1
  53. package/dist/middleware/session.js +62 -55
  54. package/dist/middleware/skip-waypoint.js +2 -2
  55. package/dist/middleware/steer-journey.d.ts +2 -1
  56. package/dist/middleware/steer-journey.js +3 -0
  57. package/dist/middleware/validate-fields.js +7 -6
  58. package/dist/mjs/esm-wrapper.js +10 -0
  59. package/dist/routes/ancillary.d.ts +8 -1
  60. package/dist/routes/ancillary.js +7 -2
  61. package/dist/routes/dirname.cjs +1 -1
  62. package/dist/routes/dirname.d.cts +2 -0
  63. package/dist/routes/journey.js +14 -8
  64. package/dist/routes/static.js +4 -3
  65. package/package.json +42 -25
  66. package/views/casa/layouts/main.njk +2 -2
@@ -0,0 +1,464 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.validateEvents = exports.validatePlugins = exports.validateGlobalHooks = exports.validatePlan = exports.validatePages = exports.validateFields = exports.validatePageHooks = exports.validateSessionCookieSameSite = exports.validateSessionCookiePath = exports.validateSessionStore = exports.validateSessionSecure = exports.validateSessionName = exports.validateSessionTtl = exports.validateSessionSecret = exports.validateViews = exports.validateSessionObject = exports.validateMountUrl = exports.validateI18nLocales = exports.validateI18nDirs = exports.validateI18nObject = void 0;
7
+ /* eslint-disable sonarjs/no-duplicate-string */
8
+ const field_js_1 = require("./field.js");
9
+ const Plan_js_1 = __importDefault(require("./Plan.js"));
10
+ const logger_js_1 = __importDefault(require("./logger.js"));
11
+ const utils_js_1 = require("./utils.js");
12
+ /**
13
+ * @typedef {import('./index').ContextEvent} ContextEvent
14
+ */
15
+ /**
16
+ * @typedef {object} SessionOptions
17
+ * @property {string} [name=casasession] Session name
18
+ * @property {string} [secret=secret] Encryption secret
19
+ * @property {number} [ttl=3600] Session ttl (seconds)
20
+ * @property {boolean} [secure=false] Whether to use secure session cookies
21
+ * @property {boolean|string} [cookieSameSite=true] SameSite (true = Strict)
22
+ * @property {object} [store] Session store (default MemoryStore)
23
+ */
24
+ /**
25
+ * @typedef {object} I18nOptions
26
+ * @property {string[]} dirs Directories to search for locale dictionaries
27
+ * @property {string[]} [locales=['en', 'cy']] Supported locales
28
+ */
29
+ /**
30
+ * @typedef {object} GlobalHook Hook configuration
31
+ * @property {string} hook Hook name in format `<router>.<hook>`
32
+ * @property {Function} middleware Middleware function to insert at the hook point
33
+ * @property {string|RegExp} [path=undefined] Only run if route path matches this string/regexp
34
+ */
35
+ /**
36
+ * @typedef {object} PageHook (extends GlobalHook)
37
+ * @property {string} hook Hook name (without a scope prefix)
38
+ * @property {Function} middleware Middleware function to insert at the hook point
39
+ */
40
+ /**
41
+ * @typedef {object} Page Page configuration. A Page is the interactive representation of a waypoint
42
+ * @property {string} waypoint The waypoint with which this page is associated
43
+ * @property {string} view Template path
44
+ * @property {PageHook[]} [hooks=[]] Page-specific hooks (optional, default [])
45
+ * @property {PageField[]} [fields=[]] Fields to be managed on this page (optional, default [])
46
+ */
47
+ /**
48
+ * Configure some middleware for use in creating a new CASA app.
49
+ *
50
+ * `mountUrl` is used to ensure the CSS content uses the correct reference to
51
+ * static assets in the `govuk-frontend` module.
52
+ *
53
+ * @typedef {object} ConfigurationOptions Configuration options
54
+ * @property {string} [mountUrl=/] URL path to root of CASA app
55
+ * @property {string[]} [views=[]] Template directories
56
+ * @property {SessionOptions} [session] Session configuration
57
+ * @property {Page[]} [pages=[]] Pages the represent waypoints
58
+ * @property {GlobalHook[]} [hooks=[]] Hooks to apply
59
+ * @property {object[]} [plugins=[]] Plugins
60
+ * @property {I18nOptions[]} [i18n] I18n configuration
61
+ * @property {Plan} plan CASA Plan
62
+ * @property {ContextEvent[]} [events=[]] Handlers for JourneyContext events
63
+ */
64
+ const log = (0, logger_js_1.default)('lib:configuration-ingestor');
65
+ const echo = (a) => (a);
66
+ /**
67
+ * Validates and sanitises i18n obejct.
68
+ *
69
+ * @param {object} i18n Object to validate.
70
+ * @param {Function} cb Callback function that receives the validated value.
71
+ * @throws {TypeError} For invalid object.
72
+ * @returns {object} Sanitised i18n object.
73
+ */
74
+ function validateI18nObject(i18n, cb = echo) {
75
+ if (Object.prototype.toString.call(i18n) !== '[object Object]') {
76
+ throw new TypeError('I18n must be an object');
77
+ }
78
+ return cb(i18n);
79
+ }
80
+ exports.validateI18nObject = validateI18nObject;
81
+ /**
82
+ * Validates and sanitises i18n directory.
83
+ *
84
+ * @param {Array} dirs Array of directories.
85
+ * @throws {SyntaxError} For invalid directories.
86
+ * @throws {TypeError} For invalid type.
87
+ * @returns {Array} Array of directories.
88
+ */
89
+ function validateI18nDirs(dirs) {
90
+ if (typeof dirs === 'undefined') {
91
+ throw ReferenceError('I18n directories are missing (i18n.dirs)');
92
+ }
93
+ else if (!Array.isArray(dirs)) {
94
+ throw new TypeError('I18n directories must be an array (i18n.dirs)');
95
+ }
96
+ dirs.forEach((dir, i) => {
97
+ if (typeof dir !== 'string') {
98
+ throw new TypeError(`I18n directory must be a string, got ${typeof dir} (i18n.dirs[${i}])`);
99
+ }
100
+ });
101
+ return dirs;
102
+ }
103
+ exports.validateI18nDirs = validateI18nDirs;
104
+ /**
105
+ * Validates and sanitises i18n locales.
106
+ *
107
+ * @param {Array} locales Array of locales.
108
+ * @throws {SyntaxError} For invalid locales.
109
+ * @throws {TypeError} For invalid type.
110
+ * @returns {Array} Array of locales.
111
+ */
112
+ function validateI18nLocales(locales) {
113
+ if (typeof locales === 'undefined') {
114
+ throw ReferenceError('I18n locales are missing (i18n.locales)');
115
+ }
116
+ else if (!Array.isArray(locales)) {
117
+ throw new TypeError('I18n locales must be an array (i18n.locales)');
118
+ }
119
+ locales.forEach((locale, i) => {
120
+ if (typeof locale !== 'string') {
121
+ throw new TypeError(`I18n locale must be a string, got ${typeof locale} (i18n.locales[${i}])`);
122
+ }
123
+ });
124
+ return locales;
125
+ }
126
+ exports.validateI18nLocales = validateI18nLocales;
127
+ /**
128
+ * Validates and sanitises mount url.
129
+ *
130
+ * @param {string} mountUrl URL from which Express app will be served.
131
+ * @param {string} name Name of the URL type (Mount URL, or Proxy Mount URL).
132
+ * @throws {SyntaxError} For invalid URL.
133
+ * @returns {string} Sanitised URL.
134
+ */
135
+ function validateMountUrl(mountUrl, name = 'Mount URL') {
136
+ if (typeof mountUrl === 'undefined') {
137
+ return '/';
138
+ }
139
+ if (!mountUrl.match(/\/$/)) {
140
+ throw new SyntaxError(`${name} must include a trailing slash (/)`);
141
+ }
142
+ return mountUrl;
143
+ }
144
+ exports.validateMountUrl = validateMountUrl;
145
+ /**
146
+ * Validates and sanitises sessions object.
147
+ *
148
+ * @param {object} session Object to validate.
149
+ * @param {Function} cb Callback function that receives the validated value.
150
+ * @throws {TypeError} For invalid object.
151
+ * @returns {object} Sanitised sessions object.
152
+ */
153
+ function validateSessionObject(session, cb = echo) {
154
+ if (session === undefined) {
155
+ return cb(session);
156
+ }
157
+ if (typeof session !== 'object') {
158
+ throw new TypeError('Session config has not been specified');
159
+ }
160
+ return cb(session);
161
+ }
162
+ exports.validateSessionObject = validateSessionObject;
163
+ /**
164
+ * Validates and sanitises view directory.
165
+ *
166
+ * @param {Array} dirs Array of directories.
167
+ * @throws {SyntaxError} For invalid directories.
168
+ * @throws {TypeError} For invalid type.
169
+ * @returns {Array} Array of directories.
170
+ */
171
+ function validateViews(dirs) {
172
+ if (typeof dirs === 'undefined') {
173
+ throw ReferenceError('View directories are missing (views)');
174
+ }
175
+ else if (!Array.isArray(dirs)) {
176
+ throw new TypeError('View directories must be an array (views)');
177
+ }
178
+ dirs.forEach((dir, i) => {
179
+ if (typeof dir !== 'string') {
180
+ throw new TypeError(`View directory must be a string, got ${typeof dir} (views[${i}])`);
181
+ }
182
+ });
183
+ return dirs;
184
+ }
185
+ exports.validateViews = validateViews;
186
+ /**
187
+ * Validates and sanitises sessions secret.
188
+ *
189
+ * @param {string} secret Session secret.
190
+ * @throws {ReferenceError} For missing value type.
191
+ * @throws {TypeError} For invalid value.
192
+ * @returns {string} Secret.
193
+ */
194
+ function validateSessionSecret(secret) {
195
+ if (typeof secret === 'undefined') {
196
+ throw ReferenceError('Session secret is missing (session.secret)');
197
+ }
198
+ else if (typeof secret !== 'string') {
199
+ throw new TypeError('Session secret must be a string (session.secret)');
200
+ }
201
+ return secret;
202
+ }
203
+ exports.validateSessionSecret = validateSessionSecret;
204
+ /**
205
+ * Validates and sanitises sessions ttl.
206
+ *
207
+ * @param {number} ttl Session ttl (seconds).
208
+ * @throws {ReferenceError} For missing value type.
209
+ * @throws {TypeError} For invalid value.
210
+ * @returns {number} Ttl.
211
+ */
212
+ function validateSessionTtl(ttl) {
213
+ if (typeof ttl === 'undefined') {
214
+ throw ReferenceError('Session ttl is missing (session.ttl)');
215
+ }
216
+ else if (typeof ttl !== 'number') {
217
+ throw new TypeError('Session ttl must be an integer (session.ttl)');
218
+ }
219
+ return ttl;
220
+ }
221
+ exports.validateSessionTtl = validateSessionTtl;
222
+ /**
223
+ * Validates and sanitises sessions name.
224
+ *
225
+ * @param {string} name Session name.
226
+ * @throws {ReferenceError} For missing value type.
227
+ * @throws {TypeError} For invalid value.
228
+ * @returns {string} Name.
229
+ */
230
+ function validateSessionName(name) {
231
+ if (typeof name === 'undefined') {
232
+ throw ReferenceError('Session name is missing (session.name)');
233
+ }
234
+ else if (typeof name !== 'string') {
235
+ throw new TypeError('Session name must be a string (session.name)');
236
+ }
237
+ return name;
238
+ }
239
+ exports.validateSessionName = validateSessionName;
240
+ /**
241
+ * Validates and sanitises sessions secure flag.
242
+ *
243
+ * @param {boolean} secure Session secure flag.
244
+ * @throws {ReferenceError} For missing value type.
245
+ * @throws {TypeError} For invalid value.
246
+ * @returns {string} Name.
247
+ */
248
+ function validateSessionSecure(secure) {
249
+ if (typeof secure === 'undefined') {
250
+ throw ReferenceError('Session secure flag is missing (session.secure)');
251
+ }
252
+ else if (typeof secure !== 'boolean') {
253
+ throw new TypeError('Session secure flag must be boolean (session.secure)');
254
+ }
255
+ return secure;
256
+ }
257
+ exports.validateSessionSecure = validateSessionSecure;
258
+ /**
259
+ * Validates and sanitises sessions store.
260
+ *
261
+ * @param {Function} store Session store.
262
+ * @returns {Function} Store.
263
+ */
264
+ function validateSessionStore(store) {
265
+ if (typeof store === 'undefined') {
266
+ log.warn('Using MemoryStore session storage, which is not suitable for production');
267
+ return null;
268
+ }
269
+ return store;
270
+ }
271
+ exports.validateSessionStore = validateSessionStore;
272
+ /**
273
+ * Validates and sanitises sessions cookie url path.
274
+ *
275
+ * @param {string} cookiePath Session cookie url path.
276
+ * @param {string} defaultPath Default path if none specified.
277
+ * @returns {string} Cookie path.
278
+ */
279
+ function validateSessionCookiePath(cookiePath, defaultPath = '/') {
280
+ if (typeof cookiePath === 'undefined') {
281
+ return defaultPath;
282
+ }
283
+ return cookiePath;
284
+ }
285
+ exports.validateSessionCookiePath = validateSessionCookiePath;
286
+ /**
287
+ * Validates and sanitises sessions cookie "sameSite" flag. One of:
288
+ * true (Strict)
289
+ * false (will not set the flag at all)
290
+ * Strict
291
+ * Lax
292
+ * None
293
+ *
294
+ * @param {any} cookieSameSite Session cookie "sameSite" flag
295
+ * @param {any} defaultFlag Default path if none specified
296
+ * @returns {boolean} cookie path
297
+ * @throws {TypeError} When invalid arguments are provided
298
+ */
299
+ function validateSessionCookieSameSite(cookieSameSite, defaultFlag) {
300
+ const validValues = [true, false, 'Strict', 'Lax', 'None'];
301
+ if (defaultFlag === undefined) {
302
+ throw new TypeError('validateSessionCookieSameSite() requires an explicit default flag');
303
+ }
304
+ else if (!validValues.includes(defaultFlag)) {
305
+ throw new TypeError('validateSessionCookieSameSite() default flag must be set to one of true, false, Strict, Lax or None (session.cookieSameSite)');
306
+ }
307
+ const value = cookieSameSite !== undefined ? cookieSameSite : defaultFlag;
308
+ if (!validValues.includes(value)) {
309
+ throw new TypeError('SameSite flag must be set to one of true, false, Strict, Lax or None (session.cookieSameSite)');
310
+ }
311
+ return value;
312
+ }
313
+ exports.validateSessionCookieSameSite = validateSessionCookieSameSite;
314
+ const validatePageHook = (hook, index) => {
315
+ try {
316
+ (0, utils_js_1.validateHookName)(hook.hook);
317
+ if (typeof hook.middleware !== 'function') {
318
+ throw new TypeError('Hook middleware must be a function');
319
+ }
320
+ }
321
+ catch (err) {
322
+ err.message = `Page hook at index ${index} is invalid: ${err.message}`;
323
+ throw err;
324
+ }
325
+ };
326
+ function validatePageHooks(hooks) {
327
+ if (!Array.isArray(hooks)) {
328
+ throw new TypeError('Hooks must be an array');
329
+ }
330
+ hooks.forEach((hook, index) => validatePageHook(hook, index));
331
+ return hooks;
332
+ }
333
+ exports.validatePageHooks = validatePageHooks;
334
+ const validateField = (field, index) => {
335
+ try {
336
+ if (!(field instanceof field_js_1.PageField)) {
337
+ throw new TypeError('Page field must be an instance of PageField (created via the "field()" function)');
338
+ }
339
+ }
340
+ catch (err) {
341
+ err.message = `Page field at index ${index} is invalid: ${err.message}`;
342
+ throw err;
343
+ }
344
+ };
345
+ function validateFields(fields) {
346
+ if (!Array.isArray(fields)) {
347
+ throw new TypeError('Page fields must be an array (page[].fields)');
348
+ }
349
+ fields.forEach((hook, index) => validateField(hook, index));
350
+ return fields;
351
+ }
352
+ exports.validateFields = validateFields;
353
+ const validatePage = (page, index) => {
354
+ try {
355
+ (0, utils_js_1.validateWaypoint)(page.waypoint);
356
+ (0, utils_js_1.validateView)(page.view);
357
+ if (page.fields !== undefined) {
358
+ validateFields(page.fields);
359
+ }
360
+ if (page.hooks !== undefined) {
361
+ validatePageHooks(page.hooks);
362
+ }
363
+ }
364
+ catch (err) {
365
+ err.message = `Page at index ${index} is invalid: ${err.message}`;
366
+ throw err;
367
+ }
368
+ };
369
+ function validatePages(pages) {
370
+ if (!Array.isArray(pages)) {
371
+ throw new TypeError('Pages must be an array (pages)');
372
+ }
373
+ pages.forEach((page, index) => validatePage(page, index));
374
+ return pages;
375
+ }
376
+ exports.validatePages = validatePages;
377
+ function validatePlan(plan) {
378
+ if (plan === undefined) {
379
+ return plan;
380
+ }
381
+ if (!(plan instanceof Plan_js_1.default)) {
382
+ throw new TypeError('Plan must be an instance the Plan class (plan)');
383
+ }
384
+ return plan;
385
+ }
386
+ exports.validatePlan = validatePlan;
387
+ const validateGlobalHook = (hook, index) => {
388
+ try {
389
+ (0, utils_js_1.validateHookName)(hook.hook);
390
+ if (typeof hook.middleware !== 'function') {
391
+ throw new TypeError('Hook middleware must be a function');
392
+ }
393
+ if (hook.path !== undefined) {
394
+ (0, utils_js_1.validateHookPath)(hook.path);
395
+ }
396
+ }
397
+ catch (err) {
398
+ err.message = `Global hook at index ${index} is invalid: ${err.message}`;
399
+ throw err;
400
+ }
401
+ };
402
+ function validateGlobalHooks(hooks) {
403
+ if (hooks === undefined) {
404
+ return [];
405
+ }
406
+ if (!Array.isArray(hooks)) {
407
+ throw new TypeError('Hooks must be an array');
408
+ }
409
+ hooks.forEach((hook, index) => validateGlobalHook(hook, index));
410
+ return hooks;
411
+ }
412
+ exports.validateGlobalHooks = validateGlobalHooks;
413
+ function validatePlugins(plugins) {
414
+ return plugins;
415
+ }
416
+ exports.validatePlugins = validatePlugins;
417
+ function validateEvents(events) {
418
+ return events;
419
+ }
420
+ exports.validateEvents = validateEvents;
421
+ /**
422
+ * Ingest, validate, sanitise and manipulate configuration parameters.
423
+ *
424
+ * @param {ConfigurationOptions} config Config to ingest.
425
+ * @throws {Error|SyntaxError|TypeError} For invalid config values.
426
+ * @returns {object} Immutable config object.
427
+ */
428
+ function ingest(config = {}) {
429
+ const parsed = {
430
+ // I18n configuration
431
+ i18n: validateI18nObject(config.i18n, (i18n) => ({
432
+ dirs: validateI18nDirs(i18n.dirs),
433
+ locales: validateI18nLocales(i18n.locales),
434
+ })),
435
+ // Public URL from which the app will be served
436
+ mountUrl: validateMountUrl(config.mountUrl),
437
+ // Session
438
+ session: validateSessionObject(config.session, (session) => ({
439
+ name: validateSessionName(session.name),
440
+ secret: validateSessionSecret(session.secret),
441
+ secure: validateSessionSecure(session.secure),
442
+ ttl: validateSessionTtl(session.ttl),
443
+ store: validateSessionStore(session.store),
444
+ cookiePath: validateSessionCookiePath(session.cookiePath, '/'),
445
+ cookieSameSite: validateSessionCookieSameSite(session.cookieSameSite, 'Strict'),
446
+ })),
447
+ // Views configuration
448
+ views: validateViews(config.views),
449
+ // Pages
450
+ pages: validatePages(config.pages),
451
+ // Plan
452
+ plan: validatePlan(config.plan),
453
+ // Hooks
454
+ hooks: validateGlobalHooks(config.hooks),
455
+ // Plugins
456
+ plugins: validatePlugins(config.plugins),
457
+ // Events
458
+ events: validateEvents(config.events),
459
+ };
460
+ // Freeze to modifications
461
+ Object.freeze(parsed);
462
+ return parsed;
463
+ }
464
+ exports.default = ingest;
@@ -1,30 +1,11 @@
1
1
  /**
2
- *
3
- * @typedef {object} SessionOptions
4
- * @property {string} [name=casasession] Session name
5
- * @property {string} [secret=secret] Encryption secret
6
- * @property {number} [ttl=3600] Session ttl (seconds)
7
- * @property {boolean} [secure=false] Whether to use secure session cookies
8
- * @property {boolean|string} [cookieSameSite=true] SameSite (true = Strict)
9
- * @property {object} [store] Session store (default MemoryStore)
10
- */
11
- /**
12
- * @typedef {object} GlobalHook Hook configuration
13
- * @property {string} hook Hook name in format `<router>.<hook>`
14
- * @property {Function} middleware Middleware function to insert at the hook point
15
- * @property {string|RegExp} [path=undefined] Only run if route path matches this string/regexp
2
+ * @typedef {import('express').RequestHandler} ExpressRequestHandler
16
3
  */
17
4
  /**
18
- * @typedef {object} PageHook (extends GlobalHook)
19
- * @property {string} hook Hook name (without a scope prefix)
20
- * @property {Function} middleware Middleware function to insert at the hook point
5
+ * @typedef {import('./index').MutableRouter} MutableRouter
21
6
  */
22
7
  /**
23
- * @typedef {object} Page Page configuration. A Page is the interactive representation of a waypoint
24
- * @property {string} waypoint The waypoint with which this page is associated
25
- * @property {string} view Template path
26
- * @property {PageHook[]} [hooks=[]] Page-specific hooks (optional, default [])
27
- * @property {PageField[]} [fields=[]] Fields to be managed on this page (optional, default [])
8
+ * @typedef {import('./configuration-ingestor').ConfigurationOptions} ConfigurationOptions
28
9
  */
29
10
  /**
30
11
  * @typedef {object} ConfigureResult Result of a call to configure() function
@@ -32,13 +13,13 @@
32
13
  * @property {MutableRouter} staticRouter Router handling all static assets
33
14
  * @property {MutableRouter} ancillaryRouter Router handling ancillary routes
34
15
  * @property {MutableRouter} journeyRouter Router handling all waypoint requests
35
- * @property {express.RequestHandler[]} preMiddleware Middleware mounted before anything else
36
- * @property {express.RequestHandler[]} postMiddleware Middleware mounted after everything else
37
- * @property {express.RequestHandler[]} csrfMiddleware CSRF get/set middleware (useful for forms)
38
- * @property {express.RequestHandler} sessionMiddleware Session middleware
39
- * @property {express.RequestHandler[]} cookieParserMiddleware Cookie-parsing middleware
40
- * @property {express.RequestHandler[]} i18nMiddleware I18n preparation middleware
41
- * @property {express.RequestHandler} bodyParserMiddleware Body parsing middleware
16
+ * @property {ExpressRequestHandler[]} preMiddleware Middleware mounted before anything else
17
+ * @property {ExpressRequestHandler[]} postMiddleware Middleware mounted after everything else
18
+ * @property {ExpressRequestHandler[]} csrfMiddleware CSRF get/set middleware (useful for forms)
19
+ * @property {ExpressRequestHandler} sessionMiddleware Session middleware
20
+ * @property {ExpressRequestHandler[]} cookieParserMiddleware Cookie-parsing middleware
21
+ * @property {ExpressRequestHandler[]} i18nMiddleware I18n preparation middleware
22
+ * @property {ExpressRequestHandler} bodyParserMiddleware Body parsing middleware
42
23
  * @property {Function} mount Function used to mount all CASA artifacts onto an ExpressJS app
43
24
  */
44
25
  /**
@@ -47,108 +28,13 @@
47
28
  * `mountUrl` is used to ensure the CSS content uses the correct reference to
48
29
  * static assets in the `govuk-frontend` module.
49
30
  *
50
- * @param {object} config Configuration options
51
- * @param {string} [config.mountUrl=/] URL path to root of CASA app
52
- * @param {string} [config.serviceName=common.serviceName] Service name (i18n key)
53
- * @param {string[]} [config.views=[]] Template directories
54
- * @param {SessionOptions} [config.session] Session configuration
55
- * @param {Page[]} [config.pages=[]] Pages the represent waypoints
56
- * @param {GlobalHook[]} [config.hooks=[]] Hooks to apply
57
- * @param {object[]} [config.plugins=[]] Plugins
58
- * @param {I18nOptions[]} [config.i18n] I18n configuration
59
- * @param {Plan} config.plan CASA Plan
60
- * @param {ContextEvent[]} [config.events=[]] Handlers for JourneyContext events
31
+ * @param {ConfigurationOptions} config Configuration options
61
32
  * @returns {ConfigureResult} Result
62
33
  */
63
- export default function configure(config?: {
64
- mountUrl?: string | undefined;
65
- serviceName?: string | undefined;
66
- views?: string[] | undefined;
67
- session?: SessionOptions | undefined;
68
- pages?: Page[] | undefined;
69
- hooks?: GlobalHook[] | undefined;
70
- plugins?: object[] | undefined;
71
- i18n?: any[] | undefined;
72
- plan: any;
73
- events?: any[] | undefined;
74
- }): ConfigureResult;
75
- export type SessionOptions = {
76
- /**
77
- * Session name
78
- */
79
- name?: string | undefined;
80
- /**
81
- * Encryption secret
82
- */
83
- secret?: string | undefined;
84
- /**
85
- * Session ttl (seconds)
86
- */
87
- ttl?: number | undefined;
88
- /**
89
- * Whether to use secure session cookies
90
- */
91
- secure?: boolean | undefined;
92
- /**
93
- * SameSite (true = Strict)
94
- */
95
- cookieSameSite?: string | boolean | undefined;
96
- /**
97
- * Session store (default MemoryStore)
98
- */
99
- store?: object | undefined;
100
- };
101
- /**
102
- * Hook configuration
103
- */
104
- export type GlobalHook = {
105
- /**
106
- * Hook name in format `<router>.<hook>`
107
- */
108
- hook: string;
109
- /**
110
- * Middleware function to insert at the hook point
111
- */
112
- middleware: Function;
113
- /**
114
- * Only run if route path matches this string/regexp
115
- */
116
- path?: string | RegExp | undefined;
117
- };
118
- /**
119
- * (extends GlobalHook)
120
- */
121
- export type PageHook = {
122
- /**
123
- * Hook name (without a scope prefix)
124
- */
125
- hook: string;
126
- /**
127
- * Middleware function to insert at the hook point
128
- */
129
- middleware: Function;
130
- };
131
- /**
132
- * Page configuration. A Page is the interactive representation of a waypoint
133
- */
134
- export type Page = {
135
- /**
136
- * The waypoint with which this page is associated
137
- */
138
- waypoint: string;
139
- /**
140
- * Template path
141
- */
142
- view: string;
143
- /**
144
- * Page-specific hooks (optional, default [])
145
- */
146
- hooks?: PageHook[] | undefined;
147
- /**
148
- * Fields to be managed on this page (optional, default [])
149
- */
150
- fields?: any[] | undefined;
151
- };
34
+ export default function configure(config?: ConfigurationOptions): ConfigureResult;
35
+ export type ExpressRequestHandler = import('express').RequestHandler;
36
+ export type MutableRouter = import('./index').MutableRouter;
37
+ export type ConfigurationOptions = import('./configuration-ingestor').ConfigurationOptions;
152
38
  /**
153
39
  * Result of a call to configure() function
154
40
  */
@@ -156,47 +42,47 @@ export type ConfigureResult = {
156
42
  /**
157
43
  * Nunjucks environment
158
44
  */
159
- nunjucksEnv: any;
45
+ nunjucksEnv: nunjucks.Environment;
160
46
  /**
161
47
  * Router handling all static assets
162
48
  */
163
- staticRouter: any;
49
+ staticRouter: MutableRouter;
164
50
  /**
165
51
  * Router handling ancillary routes
166
52
  */
167
- ancillaryRouter: any;
53
+ ancillaryRouter: MutableRouter;
168
54
  /**
169
55
  * Router handling all waypoint requests
170
56
  */
171
- journeyRouter: any;
57
+ journeyRouter: MutableRouter;
172
58
  /**
173
59
  * Middleware mounted before anything else
174
60
  */
175
- preMiddleware: any[];
61
+ preMiddleware: ExpressRequestHandler[];
176
62
  /**
177
63
  * Middleware mounted after everything else
178
64
  */
179
- postMiddleware: any[];
65
+ postMiddleware: ExpressRequestHandler[];
180
66
  /**
181
67
  * CSRF get/set middleware (useful for forms)
182
68
  */
183
- csrfMiddleware: any[];
69
+ csrfMiddleware: ExpressRequestHandler[];
184
70
  /**
185
71
  * Session middleware
186
72
  */
187
- sessionMiddleware: any;
73
+ sessionMiddleware: ExpressRequestHandler;
188
74
  /**
189
75
  * Cookie-parsing middleware
190
76
  */
191
- cookieParserMiddleware: any[];
77
+ cookieParserMiddleware: ExpressRequestHandler[];
192
78
  /**
193
79
  * I18n preparation middleware
194
80
  */
195
- i18nMiddleware: any[];
81
+ i18nMiddleware: ExpressRequestHandler[];
196
82
  /**
197
83
  * Body parsing middleware
198
84
  */
199
- bodyParserMiddleware: any;
85
+ bodyParserMiddleware: ExpressRequestHandler;
200
86
  /**
201
87
  * Function used to mount all CASA artifacts onto an ExpressJS app
202
88
  */