@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.
Files changed (49) hide show
  1. package/dist/casa.d.ts +2 -1
  2. package/dist/casa.js +3 -1
  3. package/dist/lib/CasaTemplateLoader.d.ts +6 -2
  4. package/dist/lib/CasaTemplateLoader.js +4 -1
  5. package/dist/lib/JourneyContext.d.ts +37 -6
  6. package/dist/lib/JourneyContext.js +21 -6
  7. package/dist/lib/MutableRouter.js +3 -1
  8. package/dist/lib/Plan.d.ts +37 -4
  9. package/dist/lib/Plan.js +63 -6
  10. package/dist/lib/ValidationError.d.ts +6 -2
  11. package/dist/lib/ValidationError.js +3 -0
  12. package/dist/lib/ValidatorFactory.d.ts +72 -19
  13. package/dist/lib/ValidatorFactory.js +33 -20
  14. package/dist/lib/configuration-ingestor.d.ts +262 -0
  15. package/dist/lib/configuration-ingestor.js +490 -0
  16. package/dist/lib/configure.d.ts +26 -140
  17. package/dist/lib/configure.js +16 -43
  18. package/dist/lib/dirname.d.cts +2 -0
  19. package/dist/lib/end-session.d.ts +2 -1
  20. package/dist/lib/end-session.js +24 -7
  21. package/dist/lib/field.d.ts +38 -45
  22. package/dist/lib/field.js +56 -34
  23. package/dist/lib/index.d.ts +14 -0
  24. package/dist/lib/index.js +54 -0
  25. package/dist/lib/logger.d.ts +2 -1
  26. package/dist/lib/logger.js +2 -3
  27. package/dist/lib/utils.d.ts +18 -2
  28. package/dist/lib/utils.js +54 -2
  29. package/dist/lib/waypoint-url.d.ts +2 -1
  30. package/dist/lib/waypoint-url.js +3 -0
  31. package/dist/middleware/body-parser.js +2 -2
  32. package/dist/middleware/data.d.ts +1 -2
  33. package/dist/middleware/data.js +4 -8
  34. package/dist/middleware/dirname.d.cts +2 -0
  35. package/dist/middleware/gather-fields.d.ts +2 -1
  36. package/dist/middleware/gather-fields.js +3 -0
  37. package/dist/middleware/post.js +6 -6
  38. package/dist/middleware/sanitise-fields.js +4 -4
  39. package/dist/middleware/session.d.ts +2 -1
  40. package/dist/middleware/session.js +2 -2
  41. package/dist/middleware/steer-journey.d.ts +2 -1
  42. package/dist/middleware/steer-journey.js +3 -0
  43. package/dist/routes/ancillary.d.ts +8 -1
  44. package/dist/routes/ancillary.js +7 -0
  45. package/dist/routes/dirname.d.cts +2 -0
  46. package/dist/routes/journey.js +9 -2
  47. package/dist/routes/static.js +4 -3
  48. package/package.json +27 -17
  49. package/views/casa/layouts/main.njk +2 -2
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ /**
3
+ * Just used to collate type information for intellisense. This should not get
4
+ * imported anywhere in code, other than JSDoc references.
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.waypointUrl = exports.ValidatorFactory = exports.ValidationError = exports.utils = exports.Plan = exports.MutableRouter = exports.JourneyContext = exports.PageField = exports.field = exports.endSession = exports.configurationIngestor = exports.configure = exports.CasaTemplateLoader = void 0;
30
+ const CasaTemplateLoader_js_1 = __importDefault(require("./CasaTemplateLoader.js"));
31
+ exports.CasaTemplateLoader = CasaTemplateLoader_js_1.default;
32
+ const configure_js_1 = __importDefault(require("./configure.js"));
33
+ exports.configure = configure_js_1.default;
34
+ const configuration_ingestor_js_1 = __importDefault(require("./configuration-ingestor.js"));
35
+ exports.configurationIngestor = configuration_ingestor_js_1.default;
36
+ const end_session_js_1 = __importDefault(require("./end-session.js"));
37
+ exports.endSession = end_session_js_1.default;
38
+ const field_js_1 = __importStar(require("./field.js"));
39
+ exports.field = field_js_1.default;
40
+ Object.defineProperty(exports, "PageField", { enumerable: true, get: function () { return field_js_1.PageField; } });
41
+ const JourneyContext_js_1 = __importDefault(require("./JourneyContext.js"));
42
+ exports.JourneyContext = JourneyContext_js_1.default;
43
+ const MutableRouter_js_1 = __importDefault(require("./MutableRouter.js"));
44
+ exports.MutableRouter = MutableRouter_js_1.default;
45
+ const Plan_js_1 = __importDefault(require("./Plan.js"));
46
+ exports.Plan = Plan_js_1.default;
47
+ const ValidationError_js_1 = __importDefault(require("./ValidationError.js"));
48
+ exports.ValidationError = ValidationError_js_1.default;
49
+ const ValidatorFactory_js_1 = __importDefault(require("./ValidatorFactory.js"));
50
+ exports.ValidatorFactory = ValidatorFactory_js_1.default;
51
+ const waypoint_url_js_1 = __importDefault(require("./waypoint-url.js"));
52
+ exports.waypointUrl = waypoint_url_js_1.default;
53
+ const utils = __importStar(require("./utils.js"));
54
+ exports.utils = utils;
@@ -1,4 +1,4 @@
1
- export default function _default(ns: any): {
1
+ declare function _default(ns: any): {
2
2
  trace: any;
3
3
  debug: any;
4
4
  info: any;
@@ -6,3 +6,4 @@ export default function _default(ns: any): {
6
6
  error: any;
7
7
  fatal: any;
8
8
  };
9
+ export default _default;
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const debug_1 = __importDefault(require("debug"));
7
7
  const casaDebugger = (0, debug_1.default)('casa');
8
- function default_1(ns) {
8
+ exports.default = (ns) => {
9
9
  const logger = casaDebugger.extend(ns);
10
10
  return {
11
11
  trace: logger.extend('trace'),
@@ -15,5 +15,4 @@ function default_1(ns) {
15
15
  error: logger.extend('error'),
16
16
  fatal: logger.extend('fatal'),
17
17
  };
18
- }
19
- exports.default = default_1;
18
+ };
@@ -1,3 +1,12 @@
1
+ /**
2
+ * @typedef {import('./configuration-ingestor').GlobalHook} GlobalHook
3
+ */
4
+ /**
5
+ * @typedef {import('./configuration-ingestor').PageHook} PageHook
6
+ */
7
+ /**
8
+ * @typedef {GlobalHook | PageHook} Hook
9
+ */
1
10
  /**
2
11
  * Test is a value can be stringifed (numbers or strings)
3
12
  *
@@ -27,6 +36,13 @@ export function isEmpty(val: any): boolean;
27
36
  * @param {string} hookName Hook name (including scope prefix)
28
37
  * @param {string} path URL path to match (relative to mountUrl)
29
38
  * @param {Hook[]} hooks Hooks to be applied at the page level
30
- * @returns {function[]} An array of middleware that should be applied
39
+ * @returns {Function[]} An array of middleware that should be applied
31
40
  */
32
- export function resolveMiddlewareHooks(hookName: string, path: string, hooks?: any[]): Function[];
41
+ export function resolveMiddlewareHooks(hookName: string, path: string, hooks?: Hook[]): Function[];
42
+ export function validateWaypoint(waypoint: any): void;
43
+ export function validateView(view: any): void;
44
+ export function validateHookName(hookName: any): void;
45
+ export function validateHookPath(path: any): void;
46
+ export type GlobalHook = import('./configuration-ingestor').GlobalHook;
47
+ export type PageHook = import('./configuration-ingestor').PageHook;
48
+ export type Hook = GlobalHook | PageHook;
package/dist/lib/utils.js CHANGED
@@ -1,6 +1,15 @@
1
1
  "use strict";
2
+ /**
3
+ * @typedef {import('./configuration-ingestor').GlobalHook} GlobalHook
4
+ */
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveMiddlewareHooks = exports.isEmpty = exports.stringifyInput = exports.isStringable = void 0;
6
+ exports.validateHookPath = exports.validateHookName = exports.validateView = exports.validateWaypoint = exports.resolveMiddlewareHooks = exports.isEmpty = exports.stringifyInput = exports.isStringable = void 0;
7
+ /**
8
+ * @typedef {import('./configuration-ingestor').PageHook} PageHook
9
+ */
10
+ /**
11
+ * @typedef {GlobalHook | PageHook} Hook
12
+ */
4
13
  /**
5
14
  * Test is a value can be stringifed (numbers or strings)
6
15
  *
@@ -49,7 +58,7 @@ exports.isEmpty = isEmpty;
49
58
  * @param {string} hookName Hook name (including scope prefix)
50
59
  * @param {string} path URL path to match (relative to mountUrl)
51
60
  * @param {Hook[]} hooks Hooks to be applied at the page level
52
- * @returns {function[]} An array of middleware that should be applied
61
+ * @returns {Function[]} An array of middleware that should be applied
53
62
  */
54
63
  function resolveMiddlewareHooks(hookName, path, hooks = []) {
55
64
  /* eslint-disable-next-line max-len */
@@ -57,3 +66,46 @@ function resolveMiddlewareHooks(hookName, path, hooks = []) {
57
66
  return hooks.filter((h) => h.hook === hookName).filter(pathMatch).map((h) => h.middleware);
58
67
  }
59
68
  exports.resolveMiddlewareHooks = resolveMiddlewareHooks;
69
+ /* ------------------------------------------------ validation / sanitisation */
70
+ function validateWaypoint(waypoint) {
71
+ if (typeof waypoint !== 'string') {
72
+ throw new TypeError('Waypoint must be a string');
73
+ }
74
+ if (!waypoint.length) {
75
+ throw new SyntaxError('Waypoint must not be empty');
76
+ }
77
+ if (waypoint.match(/[^/a-z0-9_-]/)) {
78
+ throw new SyntaxError('Waypoint must contain only a-z, 0-9, -, _ and / characters');
79
+ }
80
+ }
81
+ exports.validateWaypoint = validateWaypoint;
82
+ function validateView(view) {
83
+ if (typeof view !== 'string') {
84
+ throw new TypeError('View must be a string');
85
+ }
86
+ if (!view.length) {
87
+ throw new SyntaxError('View must not be empty');
88
+ }
89
+ if (!view.match(/^[a-z0-9/_-]+\.njk$/i)) {
90
+ throw new SyntaxError('View must contain only a-z, 0-9, -, _ and / characters, and end in .njk');
91
+ }
92
+ }
93
+ exports.validateView = validateView;
94
+ function validateHookName(hookName) {
95
+ if (typeof hookName !== 'string') {
96
+ throw new TypeError('Hook name must be a string');
97
+ }
98
+ if (!hookName.length) {
99
+ throw new SyntaxError('Hook name must not be empty');
100
+ }
101
+ if (!hookName.match(/^([a-z]+\.|)[a-z]+$/i)) {
102
+ throw new SyntaxError('Hook name must match either <scope>.<hookname> or <hookname> formats');
103
+ }
104
+ }
105
+ exports.validateHookName = validateHookName;
106
+ function validateHookPath(path) {
107
+ if (typeof path !== 'string' && !(path instanceof RegExp)) {
108
+ throw new TypeError('Hook path must be a string or RegExp');
109
+ }
110
+ }
111
+ exports.validateHookPath = validateHookPath;
@@ -14,9 +14,10 @@
14
14
  export default function waypointUrl({ waypoint, mountUrl, journeyContext, edit, editOrigin, skipTo, routeName, }?: {
15
15
  waypoint: string;
16
16
  mountUrl: string;
17
- journeyContext: any;
17
+ journeyContext: JourneyContext;
18
18
  edit: boolean;
19
19
  editOrigin: string;
20
20
  skipTo: boolean;
21
21
  routeName: string;
22
22
  }): string;
23
+ export type JourneyContext = import('./index').JourneyContext;
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ /**
3
+ * @typedef {import('./index').JourneyContext} JourneyContext
4
+ */
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  const reUrlProtocolExtract = /^url:\/\/(.+)$/i;
4
7
  const sanitiseWaypoint = (w) => w.replace(/[^/a-z0-9_-]/ig, '').replace(/\/+/g, '/');
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const express_1 = require("express");
4
4
  function bodyParserMiddleware() {
5
5
  const rProto = /__proto__/i;
6
- const rPrototype = /prototype[=[\]]/i;
7
- const rConstructor = /constructor[=[\]]/i;
6
+ const rPrototype = /prototype[='"[\]]/i;
7
+ const rConstructor = /constructor[='"[\]]/i;
8
8
  return [
9
9
  (0, express_1.urlencoded)({
10
10
  extended: true,
@@ -1,6 +1,5 @@
1
- export default function dataMiddleware({ plan, mountUrl, serviceName, events, }: {
1
+ export default function dataMiddleware({ plan, mountUrl, events, }: {
2
2
  plan: any;
3
3
  mountUrl: any;
4
- serviceName: any;
5
4
  events: any;
6
5
  }): ((req: any, res: any, next: any) => void)[];
@@ -18,7 +18,7 @@ const editOrigin = (req) => {
18
18
  }
19
19
  return '';
20
20
  };
21
- function dataMiddleware({ plan, mountUrl, serviceName, events, }) {
21
+ function dataMiddleware({ plan, mountUrl, events, }) {
22
22
  return [
23
23
  (req, res, next) => {
24
24
  /* ------------------------------------------------ Request decorations */
@@ -37,18 +37,14 @@ function dataMiddleware({ plan, mountUrl, serviceName, events, }) {
37
37
  // CASA and userland templates
38
38
  res.locals.casa = {
39
39
  mountUrl,
40
- serviceName,
41
40
  };
42
41
  res.locals.locale = req.language;
43
42
  // Used by govuk-frontend template
44
43
  // - req.language is provided by i18n-http-middleware
45
44
  res.locals.htmlLang = req.language;
46
- // res.locals.makeLink
47
- // res.locals.casa.journeyPreviousUrl
48
- // req.session.journeyContext
49
- // req.session.language
50
- // req.editOriginUrl
51
- // req.inEditMode
45
+ // Function for building URLs. This will be curried with the `mountUrl`
46
+ // and `journeyContext` for convenience
47
+ res.locals.waypointUrl = (args) => (0, waypoint_url_js_1.default)(Object.assign({ mountUrl, journeyContext: req.casa.journeyContext }, args));
52
48
  // req.editSearchParams
53
49
  next();
54
50
  },
@@ -0,0 +1,2 @@
1
+ declare const _exports: string;
2
+ export = _exports;
@@ -1,5 +1,6 @@
1
1
  declare function _default({ waypoint, fields, }: {
2
2
  waypoint: string;
3
- fields?: any[] | undefined;
3
+ fields?: import("../lib/field").PageField[] | undefined;
4
4
  }): any[];
5
5
  export default _default;
6
+ export type PageField = import('../lib/field').PageField;
@@ -8,6 +8,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
8
8
  };
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  const JourneyContext_js_1 = __importDefault(require("../lib/JourneyContext.js"));
11
+ /**
12
+ * @typedef {import('../lib/field').PageField} PageField
13
+ */
11
14
  /**
12
15
  * Gather the field data from `req.body` into the current JourneyContext
13
16
  * - Store in the current session
@@ -26,31 +26,31 @@ function postMiddleware({ mountUrl, }) {
26
26
  // CSRF token is invalid in some way
27
27
  if ((err === null || err === void 0 ? void 0 : err.code) === 'EBADCSRFTOKEN') {
28
28
  log.info('CSRF validation has failed. This may be caused by the user submitting a stale form from a previous session [EBADCSRFTOKEN]');
29
- return res.status(403).render(TEMPLATE);
29
+ return res.status(403).render(TEMPLATE, { errorCode: 'bad_csrf_token' });
30
30
  }
31
31
  // Body parsing verification check failed
32
32
  if ((err === null || err === void 0 ? void 0 : err.type) === 'entity.verify.failed') {
33
33
  log.info('Body parser verification has failed. This has been caused by the user submitting a payload containing invalid data [entity.verify.failed]');
34
- return res.status(403).render(TEMPLATE);
34
+ return res.status(403).render(TEMPLATE, { errorCode: 'invalid_payload' });
35
35
  }
36
36
  // Too many parameters submitted
37
37
  if ((err === null || err === void 0 ? void 0 : err.type) === 'parameters.too.many') {
38
38
  log.info('The request contains more parameters than is currently allowed [parameters.too.many]');
39
- return res.status(413).render(TEMPLATE);
39
+ return res.status(413).render(TEMPLATE, { errorCode: 'parameter_limit_exceeded' });
40
40
  }
41
41
  // Overall payload too large
42
42
  if ((err === null || err === void 0 ? void 0 : err.type) === 'entity.too.large') {
43
43
  log.info(`The request payload is too large. Received ${err.length}b with a maximum of ${err.limit}b [parameters.too.many]`);
44
- return res.status(413).render(TEMPLATE);
44
+ return res.status(413).render(TEMPLATE, { errorCode: 'payload_size_exceeded' });
45
45
  }
46
46
  // Unaccept request method
47
47
  if ((err === null || err === void 0 ? void 0 : err.code) === 'unaccepted_request_method') {
48
48
  log.info(err.message);
49
- return res.status(400).render(TEMPLATE);
49
+ return res.status(400).render(TEMPLATE, { errorCode: 'unaccepted_request_method' });
50
50
  }
51
51
  // Unknown error
52
52
  log.error(`Unknown error: ${err.message}; stacktrace: ${err.stack}`);
53
- return res.render(TEMPLATE);
53
+ return res.status(200).render(TEMPLATE);
54
54
  },
55
55
  ];
56
56
  }
@@ -11,10 +11,10 @@ const field_js_1 = __importDefault(require("../lib/field.js"));
11
11
  const JourneyContext_js_1 = __importDefault(require("../lib/JourneyContext.js"));
12
12
  exports.default = ({ waypoint, fields = [], }) => {
13
13
  // Add some common, transient fields to ensure they survive beyond this sanitisation process
14
- fields.push((0, field_js_1.default)('_csrf', { persist: false }).processor(((value) => String(value))));
15
- fields.push((0, field_js_1.default)('contextid', { persist: false }).processor(((value) => String(value))));
16
- fields.push((0, field_js_1.default)('edit', { persist: false }).processor(((value) => String(value))));
17
- fields.push((0, field_js_1.default)('editorigin', { persist: false }).processor(((value) => String(value))));
14
+ fields.push((0, field_js_1.default)('_csrf', { persist: false }).processor((value) => String(value)));
15
+ fields.push((0, field_js_1.default)('contextid', { persist: false }).processor((value) => String(value)));
16
+ fields.push((0, field_js_1.default)('edit', { persist: false }).processor((value) => String(value)));
17
+ fields.push((0, field_js_1.default)('editorigin', { persist: false }).processor((value) => String(value)));
18
18
  // Middleware
19
19
  return [
20
20
  (req, res, next) => {
@@ -1,4 +1,4 @@
1
- export default function sessionMiddleware({ cookieParserMiddleware, secret, name, secure, ttl, mountUrl, cookieSameSite, store, }: {
1
+ export default function sessionMiddleware({ cookieParserMiddleware, secret, name, secure, ttl, mountUrl, cookieSameSite, cookiePath, store, }: {
2
2
  cookieParserMiddleware: any;
3
3
  secret: any;
4
4
  name: any;
@@ -6,5 +6,6 @@ export default function sessionMiddleware({ cookieParserMiddleware, secret, name
6
6
  ttl: any;
7
7
  mountUrl?: string | undefined;
8
8
  cookieSameSite?: boolean | undefined;
9
+ cookiePath?: string | undefined;
9
10
  store?: any;
10
11
  }): any[];
@@ -32,10 +32,10 @@ const log = (0, logger_js_1.default)('middleware:session');
32
32
  // - set the session cookie
33
33
  // - parse request cookies
34
34
  // - handle expiry of server-side session
35
- function sessionMiddleware({ cookieParserMiddleware, secret, name, secure, ttl, mountUrl = '/', cookieSameSite = true, store = new express_session_1.MemoryStore(), }) {
35
+ function sessionMiddleware({ cookieParserMiddleware, secret, name, secure, ttl, mountUrl = '/', cookieSameSite = true, cookiePath = '/', store = new express_session_1.MemoryStore(), }) {
36
36
  const commonCookieOptions = {
37
37
  httpOnly: true,
38
- path: '/',
38
+ path: cookiePath,
39
39
  secure,
40
40
  };
41
41
  if (cookieSameSite !== false) {
@@ -1,6 +1,7 @@
1
1
  declare function _default({ waypoint, plan, mountUrl, }: {
2
2
  waypoint: string;
3
- plan: any;
3
+ plan: Plan;
4
4
  mountUrl: string;
5
5
  }): void;
6
6
  export default _default;
7
+ export type Plan = typeof import("../lib/Plan");
@@ -8,6 +8,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
8
8
  const waypoint_url_js_1 = __importDefault(require("../lib/waypoint-url.js"));
9
9
  const logger_js_1 = __importDefault(require("../lib/logger.js"));
10
10
  const log = (0, logger_js_1.default)('middleware:steer-journey');
11
+ /**
12
+ * @typedef {import('../lib/Plan')} Plan
13
+ */
11
14
  /**
12
15
  * This sits in front of all other journey middleware and prevents the user from
13
16
  * "jumping ahead" in the Plan.
@@ -1,4 +1,11 @@
1
+ /**
2
+ * Create an instance of the ancillary router.
3
+ *
4
+ * @param {Object} options = Optiona
5
+ * @param {number} options.sessionTtl Session timeout (seconds)
6
+ * @returns {MutableRouter} Mutable router
7
+ */
1
8
  export default function ancillaryRouter({ sessionTtl, }: {
2
- sessionTtl: any;
9
+ sessionTtl: number;
3
10
  }): MutableRouter;
4
11
  import MutableRouter from "../lib/MutableRouter.js";
@@ -4,6 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const MutableRouter_js_1 = __importDefault(require("../lib/MutableRouter.js"));
7
+ /**
8
+ * Create an instance of the ancillary router.
9
+ *
10
+ * @param {Object} options = Optiona
11
+ * @param {number} options.sessionTtl Session timeout (seconds)
12
+ * @returns {MutableRouter} Mutable router
13
+ */
7
14
  function ancillaryRouter({ sessionTtl, }) {
8
15
  // Router
9
16
  const router = new MutableRouter_js_1.default();
@@ -0,0 +1,2 @@
1
+ declare const _exports: string;
2
+ export = _exports;
@@ -80,13 +80,20 @@ function journeyRouter({ globalHooks, pages, plan, csrfMiddleware, mountUrl, })
80
80
  const { waypoint, view, hooks: pageHooks = [], fields } = page;
81
81
  const formUrl = (0, waypoint_url_js_1.default)({ mountUrl, waypoint });
82
82
  const waypointPath = `/${waypoint}`;
83
- const commonWaypointMiddleware = [
83
+ let commonWaypointMiddleware = [
84
84
  (req, res, next) => {
85
85
  req.casa.waypoint = waypoint;
86
+ res.locals.casa.waypoint = waypoint;
86
87
  next();
87
88
  },
88
- ...(0, skip_waypoint_js_1.default)({ mountUrl, waypoint }),
89
89
  ];
90
+ if (plan.isSkippable(waypoint)) {
91
+ log.info(`Configuring "${waypoint}" as a skippable waypoint`);
92
+ commonWaypointMiddleware = [
93
+ ...commonWaypointMiddleware,
94
+ ...(0, skip_waypoint_js_1.default)({ mountUrl, waypoint }),
95
+ ];
96
+ }
90
97
  router.get(waypointPath, ...commonMiddleware, ...commonWaypointMiddleware, ...(0, utils_js_1.resolveMiddlewareHooks)('journey.presteer', waypointPath, [...globalHooks, ...pageHooks]), ...(0, steer_journey_js_1.default)({ waypoint, mountUrl, plan }), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.poststeer', waypointPath, [...globalHooks, ...pageHooks]), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.prerender', waypointPath, [...globalHooks, ...pageHooks]), renderMiddlewareFactory(view, (req) => ({
91
98
  formUrl,
92
99
  formData: req.casa.journeyContext.getDataForPage(waypoint),
@@ -3,13 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const express_1 = require("express");
6
+ const express_1 = __importDefault(require("express"));
7
7
  const fs_1 = require("fs");
8
8
  const url_1 = require("url");
9
9
  const path_1 = require("path");
10
10
  const module_1 = require("module");
11
11
  const dirname_cjs_1 = __importDefault(require("./dirname.cjs"));
12
12
  const MutableRouter_js_1 = __importDefault(require("../lib/MutableRouter.js"));
13
+ const { static: ExpressStatic } = express_1.default; // CommonJS
13
14
  const oneDay = 86400000;
14
15
  /**
15
16
  * @typedef {object} StaticOptions Options to configure static router
@@ -56,8 +57,8 @@ function staticRouter({ mountUrl = '/', maxAge = 3600000, }) {
56
57
  // The static middleware will only server GET/HEAD requests, so we can mount
57
58
  // the middleware using `use()` rather than resorting to `get()`
58
59
  const govukFrontendDirectory = (0, path_1.resolve)((0, module_1.createRequire)(dirname_cjs_1.default).resolve('govuk-frontend'), '../../');
59
- router.use('/govuk/assets/js/all.js', (0, express_1.static)(`${govukFrontendDirectory}/govuk/all.js`, staticConfig));
60
- router.use('/govuk/assets', (0, express_1.static)(`${govukFrontendDirectory}/govuk/assets`, staticConfig));
60
+ router.use('/govuk/assets/js/all.js', ExpressStatic(`${govukFrontendDirectory}/govuk/all.js`, staticConfig));
61
+ router.use('/govuk/assets', ExpressStatic(`${govukFrontendDirectory}/govuk/assets`, staticConfig));
61
62
  router.use('/govuk/assets', notFoundHandler);
62
63
  router.use('/casa/assets/css/casa.css', setHeaders, (req, res) => res.send(casaCss));
63
64
  router.use('/casa/assets/css/casa-ie8.css', setHeaders, (req, res) => res.send(casaCssIe8));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dwp/govuk-casa",
3
- "version": "8.0.0-alpha2",
3
+ "version": "8.0.0-beta1",
4
4
  "description": "A framework for building GOVUK Collect-And-Submit-Applications",
5
5
  "main": "dist/casa.js",
6
6
  "module": "dist/mjs/casa.js",
@@ -18,58 +18,68 @@
18
18
  "node": ">=14.17.2"
19
19
  },
20
20
  "scripts": {
21
+ "pipeline": "npm test && npm run test:e2e && npm run lint",
21
22
  "test": "mocha './tests/**/*.test.js'",
22
23
  "test:e2e": "spiderplan --worker-init ./tests/e2e/worker-init.js --language en ./tests/e2e/personas/**/*.yaml",
24
+ "test:combined": "npm test; npm run test:e2e",
25
+ "lint": "eslint .",
26
+ "coverage": "c8 npm run test:combined",
23
27
  "build": "npm run build:prepare && npm run build:sources && npm run build:css-assets",
24
28
  "build:prepare": "rm -rf dist/* && mkdir -p dist/assets/js/ && mkdir -p dist/assets/css/",
25
29
  "build:sources": "tsc -p tsconfig-cjs.json && ./scripts/fixup.sh",
26
30
  "build:css-assets": "node scripts/compile-sass.js",
27
- "prepare": "npm run build"
31
+ "prepare": "npm run build",
32
+ "upgrade-deps": "OD=$(npm outdated --long --parseable); echo \"$OD\" | grep ':devDependencies:' | awk -F: '{ print $4 }' | xargs npm i -DE; echo \"$OD\" | grep ':dependencies:' | awk -F: '{ print $4 }' | xargs npm i -E"
28
33
  },
29
34
  "keywords": [],
30
35
  "author": "DWP Digital",
31
36
  "license": "ISC",
32
37
  "type": "module",
33
38
  "dependencies": {
34
- "cookie-parser": "1.4.5",
39
+ "cookie-parser": "1.4.6",
35
40
  "csurf": "1.11.0",
36
- "debug": "4.3.2",
41
+ "debug": "4.3.3",
37
42
  "deepmerge": "4.2.2",
38
43
  "express": "4.17.1",
39
44
  "express-session": "1.17.2",
40
45
  "govuk-frontend": "3.14.0",
41
46
  "graphlib": "2.1.8",
42
47
  "helmet": "4.6.0",
43
- "i18next": "21.3.2",
48
+ "i18next": "21.6.0",
44
49
  "i18next-http-middleware": "3.1.4",
45
50
  "js-yaml": "4.1.0",
46
51
  "lodash": "4.17.21",
47
- "luxon": "2.0.2",
52
+ "luxon": "2.1.1",
48
53
  "nunjucks": "3.2.3",
49
54
  "uuid": "8.3.2",
50
- "validator": "^13.6.0"
55
+ "validator": "^13.7.0"
51
56
  },
52
57
  "devDependencies": {
53
- "@babel/core": "7.15.8",
54
- "@babel/eslint-parser": "7.15.8",
55
- "@babel/preset-env": "7.15.8",
58
+ "@babel/core": "7.16.0",
59
+ "@babel/eslint-parser": "7.16.3",
60
+ "@babel/preset-env": "7.16.4",
61
+ "@commitlint/config-conventional": "15.0.0",
56
62
  "@dwp/casa-spiderplan": "2.0.0",
57
63
  "@dwp/casa-spiderplan-a11y-plugin": "0.1.3",
58
64
  "@dwp/casa-spiderplan-zap-plugin": "0.1.1",
59
- "@dwp/commitlint-config-base": "1.2.0",
60
65
  "@dwp/eslint-config-base": "5.0.1",
61
66
  "@types/express": "4.17.13",
62
- "@types/node": "16.11.1",
67
+ "@types/node": "16.11.12",
63
68
  "@types/nunjucks": "3.2.0",
64
69
  "babel-eslint": "10.1.0",
70
+ "c8": "7.10.0",
65
71
  "chai": "4.3.4",
66
- "commitlint": "13.2.1",
72
+ "commitlint": "15.0.0",
67
73
  "eslint": "7.32.0",
68
74
  "eslint-plugin-no-unsafe-regex": "1.0.0",
69
- "eslint-plugin-sonarjs": "0.10.0",
70
- "husky": "7.0.2",
75
+ "eslint-plugin-sonarjs": "0.11.0",
76
+ "fast-check": "2.20.0",
77
+ "husky": "7.0.4",
71
78
  "mocha": "9.1.3",
72
- "sass": "1.43.2",
73
- "typescript": "4.4.4"
79
+ "sass": "1.44.0",
80
+ "sinon": "12.0.1",
81
+ "sinon-chai": "3.7.0",
82
+ "supertest": "6.1.6",
83
+ "typescript": "4.5.3"
74
84
  }
75
85
  }
@@ -10,7 +10,7 @@
10
10
  {# Harcoding content for the skip link as t() may not be availble on some error pages #}
11
11
  {{ govukSkipLink({
12
12
  href: '#main-content',
13
- text: 'Neidio i\'r prif gynnwys' if locale === 'cy' else 'Skip to main content'
13
+ text: "Neidio i'r prif gynnwys" if locale === 'cy' else 'Skip to main content'
14
14
  }) }}
15
15
  {% endblock %}
16
16
 
@@ -18,7 +18,7 @@
18
18
  {% block header %}
19
19
  {{ govukHeader({
20
20
  assetsPath: assetPath + "/images",
21
- serviceName: t(casa.serviceName) if t else '',
21
+ serviceName: t('common:serviceName') if t else '',
22
22
  serviceUrl: casa.mountUrl,
23
23
  homepageUrl: "https://www.gov.uk/"
24
24
  }) }}