@dwp/govuk-casa 7.0.6 → 8.0.0-alpha1
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/README.md +22 -17
- package/dist/{casa → assets}/css/casa-ie8.css +1 -1
- package/dist/assets/css/casa.css +1 -0
- package/dist/casa.d.ts +10 -0
- package/dist/casa.js +44 -0
- package/dist/lib/CasaTemplateLoader.d.ts +19 -0
- package/dist/lib/CasaTemplateLoader.js +57 -0
- package/dist/lib/JourneyContext.d.ts +255 -0
- package/dist/lib/JourneyContext.js +681 -0
- package/dist/lib/MutableRouter.d.ts +155 -0
- package/dist/lib/MutableRouter.js +272 -0
- package/dist/lib/Plan.d.ts +119 -0
- package/dist/lib/Plan.js +382 -0
- package/dist/lib/ValidationError.d.ts +70 -0
- package/dist/lib/ValidationError.js +156 -0
- package/dist/lib/ValidatorFactory.d.ts +24 -0
- package/dist/lib/ValidatorFactory.js +87 -0
- package/dist/lib/configure.d.ts +205 -0
- package/dist/lib/configure.js +215 -0
- package/dist/lib/dirname.cjs +1 -0
- package/dist/lib/end-session.d.ts +12 -0
- package/dist/lib/end-session.js +24 -0
- package/dist/lib/field.d.ts +79 -0
- package/dist/lib/field.js +223 -0
- package/dist/lib/logger.d.ts +8 -0
- package/dist/lib/logger.js +19 -0
- package/dist/lib/nunjucks-filters.d.ts +26 -0
- package/dist/lib/nunjucks-filters.js +112 -0
- package/dist/lib/nunjucks.d.ts +22 -0
- package/dist/lib/nunjucks.js +49 -0
- package/dist/lib/utils.d.ts +22 -0
- package/dist/lib/utils.js +44 -0
- package/dist/lib/validators/dateObject.d.ts +4 -0
- package/dist/lib/validators/dateObject.js +135 -0
- package/dist/lib/validators/email.d.ts +4 -0
- package/dist/lib/validators/email.js +46 -0
- package/dist/lib/validators/inArray.d.ts +4 -0
- package/dist/lib/validators/inArray.js +60 -0
- package/dist/lib/validators/index.d.ts +21 -0
- package/dist/lib/validators/index.js +47 -0
- package/dist/lib/validators/nino.d.ts +4 -0
- package/dist/lib/validators/nino.js +46 -0
- package/dist/lib/validators/postalAddressObject.d.ts +4 -0
- package/dist/lib/validators/postalAddressObject.js +123 -0
- package/dist/lib/validators/regex.d.ts +4 -0
- package/dist/lib/validators/regex.js +40 -0
- package/dist/lib/validators/required.d.ts +4 -0
- package/dist/lib/validators/required.js +56 -0
- package/dist/lib/validators/strlen.d.ts +4 -0
- package/dist/lib/validators/strlen.js +51 -0
- package/dist/lib/validators/wordCount.d.ts +5 -0
- package/dist/lib/validators/wordCount.js +54 -0
- package/dist/lib/waypoint-url.d.ts +17 -0
- package/dist/lib/waypoint-url.js +46 -0
- package/dist/middleware/body-parser.d.ts +1 -0
- package/dist/middleware/body-parser.js +24 -0
- package/dist/middleware/csrf.d.ts +1 -0
- package/dist/middleware/csrf.js +31 -0
- package/dist/middleware/data.d.ts +6 -0
- package/dist/middleware/data.js +53 -0
- package/dist/middleware/dirname.cjs +1 -0
- package/dist/middleware/gather-fields.d.ts +5 -0
- package/dist/middleware/gather-fields.js +39 -0
- package/dist/middleware/i18n.d.ts +4 -0
- package/dist/middleware/i18n.js +87 -0
- package/dist/middleware/post.d.ts +1 -0
- package/dist/middleware/post.js +42 -0
- package/dist/middleware/pre.d.ts +3 -0
- package/dist/middleware/pre.js +38 -0
- package/dist/middleware/progress-journey.d.ts +6 -0
- package/dist/middleware/progress-journey.js +82 -0
- package/dist/middleware/sanitise-fields.d.ts +5 -0
- package/dist/middleware/sanitise-fields.js +48 -0
- package/dist/middleware/session.d.ts +10 -0
- package/dist/middleware/session.js +115 -0
- package/dist/middleware/skip-waypoint.d.ts +5 -0
- package/dist/middleware/skip-waypoint.js +40 -0
- package/dist/middleware/steer-journey.d.ts +6 -0
- package/dist/middleware/steer-journey.js +44 -0
- package/dist/middleware/validate-fields.d.ts +7 -0
- package/dist/middleware/validate-fields.js +76 -0
- package/dist/mjs/esm-wrapper.js +10 -0
- package/dist/mjs/package.json +3 -0
- package/dist/package.json +3 -0
- package/dist/routes/ancillary.d.ts +4 -0
- package/dist/routes/ancillary.js +19 -0
- package/dist/routes/dirname.cjs +1 -0
- package/dist/routes/journey.d.ts +8 -0
- package/dist/routes/journey.js +130 -0
- package/dist/routes/static.d.ts +26 -0
- package/dist/routes/static.js +67 -0
- package/package.json +45 -86
- package/views/casa/components/checkboxes/template.njk +4 -1
- package/views/casa/components/date-input/template.njk +3 -3
- package/views/casa/components/journey-form/README.md +3 -1
- package/views/casa/components/journey-form/template.njk +1 -1
- package/views/casa/components/postal-address-object/template.njk +5 -5
- package/views/casa/components/radios/template.njk +1 -1
- package/views/casa/layouts/journey.njk +26 -9
- package/views/casa/layouts/main.njk +6 -19
- package/views/casa/partials/scripts.njk +8 -3
- package/views/casa/partials/styles.njk +2 -2
- package/casa.js +0 -208
- package/definitions/review-page.js +0 -60
- package/dist/casa/css/casa.css +0 -1
- package/dist/casa/js/casa.js +0 -1
- package/index.d.ts +0 -121
- package/lib/ConfigIngestor.js +0 -588
- package/lib/GatherModifier.js +0 -14
- package/lib/I18n.js +0 -160
- package/lib/JourneyContext.d.ts +0 -97
- package/lib/JourneyContext.js +0 -552
- package/lib/JourneyMap.js +0 -233
- package/lib/JourneyRoad.js +0 -330
- package/lib/Logger.js +0 -59
- package/lib/PageDictionary.d.ts +0 -11
- package/lib/PageDirectory.js +0 -77
- package/lib/Plan.js +0 -423
- package/lib/RoadConverter.js +0 -153
- package/lib/UserJourney.js +0 -8
- package/lib/Util.js +0 -227
- package/lib/Validation.js +0 -20
- package/lib/bootstrap/end-session.js +0 -44
- package/lib/bootstrap/load-definitions.js +0 -64
- package/lib/commonBodyParser.js +0 -15
- package/lib/enums.js +0 -6
- package/lib/gather-modifiers/index.js +0 -7
- package/lib/gather-modifiers/trimPostalAddressObject.js +0 -75
- package/lib/gather-modifiers/trimWhitespace.js +0 -16
- package/lib/utils/createGetRequest.d.ts +0 -5
- package/lib/utils/createGetRequest.js +0 -59
- package/lib/utils/index.js +0 -11
- package/lib/utils/parseRequest.d.ts +0 -5
- package/lib/utils/parseRequest.js +0 -72
- package/lib/utils/sanitise.js +0 -74
- package/lib/utils/validate.js +0 -32
- package/lib/validation/ArrayObjectField.js +0 -49
- package/lib/validation/ObjectField.js +0 -53
- package/lib/validation/SimpleField.d.ts +0 -11
- package/lib/validation/SimpleField.js +0 -46
- package/lib/validation/ValidationError.d.ts +0 -14
- package/lib/validation/ValidationError.js +0 -170
- package/lib/validation/ValidatorFactory.d.ts +0 -32
- package/lib/validation/ValidatorFactory.js +0 -91
- package/lib/validation/index.js +0 -22
- package/lib/validation/processor/flattenErrorArray.js +0 -24
- package/lib/validation/processor/queue.js +0 -214
- package/lib/validation/processor.js +0 -84
- package/lib/validation/rules/README.md +0 -3
- package/lib/validation/rules/ValidationRules.d.ts +0 -22
- package/lib/validation/rules/dateObject.js +0 -156
- package/lib/validation/rules/email.js +0 -44
- package/lib/validation/rules/inArray.js +0 -61
- package/lib/validation/rules/index.js +0 -23
- package/lib/validation/rules/nino.js +0 -48
- package/lib/validation/rules/optional.js +0 -14
- package/lib/validation/rules/postalAddressObject.js +0 -142
- package/lib/validation/rules/regex.js +0 -39
- package/lib/validation/rules/required.js +0 -57
- package/lib/validation/rules/strlen.js +0 -57
- package/lib/validation/rules/wordCount.js +0 -61
- package/lib/view-filters/formatDateObject.js +0 -35
- package/lib/view-filters/includes.js +0 -10
- package/lib/view-filters/index.js +0 -23
- package/lib/view-filters/mergeObjectsDeep.js +0 -21
- package/lib/view-filters/renderAsAttributes.js +0 -33
- package/middleware/errors/404.js +0 -12
- package/middleware/errors/catch-all.js +0 -27
- package/middleware/errors/index.js +0 -9
- package/middleware/headers/config-defaults.js +0 -57
- package/middleware/headers/headers.js +0 -40
- package/middleware/headers/index.js +0 -9
- package/middleware/i18n/i18n.js +0 -56
- package/middleware/i18n/index.js +0 -16
- package/middleware/index.js +0 -55
- package/middleware/mount/index.js +0 -9
- package/middleware/mount/mount.js +0 -10
- package/middleware/nunjucks/environment.js +0 -57
- package/middleware/nunjucks/index.js +0 -8
- package/middleware/page/csrf.js +0 -37
- package/middleware/page/edit-mode.js +0 -52
- package/middleware/page/gather.js +0 -75
- package/middleware/page/index.js +0 -103
- package/middleware/page/journey-continue.js +0 -157
- package/middleware/page/journey-rails.js +0 -102
- package/middleware/page/prepare-request.js +0 -77
- package/middleware/page/render.js +0 -75
- package/middleware/page/skip.js +0 -72
- package/middleware/page/utils.js +0 -206
- package/middleware/page/validate.js +0 -67
- package/middleware/session/expiry.js +0 -95
- package/middleware/session/genid.js +0 -18
- package/middleware/session/index.js +0 -18
- package/middleware/session/init.js +0 -25
- package/middleware/session/seed.js +0 -50
- package/middleware/session/timeout.js +0 -5
- package/middleware/static/asset-versions.js +0 -23
- package/middleware/static/index.js +0 -104
- package/middleware/static/prepare-assets.js +0 -51
- package/middleware/static/serve-assets.js +0 -58
- package/middleware/variables/index.js +0 -12
- package/middleware/variables/variables.js +0 -35
- package/src/browserconfig.xml +0 -5
- package/src/js/casa.js +0 -132
- package/src/scss/_casaElements.scss +0 -11
- package/src/scss/_casaGovukTemplateJinjaPolyfill.scss +0 -39
- package/src/scss/_casaMountUrl.scss +0 -8
- package/src/scss/casa-ie8.scss +0 -3
- package/src/scss/casa.scss +0 -14
- package/test/unit/templates/README.md +0 -5
- package/test/utils/BaseTestWaypoint.js +0 -106
- package/test/utils/concatWaypoints.js +0 -26
- package/test/utils/index.js +0 -6
- package/test/utils/testTraversal.js +0 -90
- package/views/casa/partials/cookie_message.njk +0 -3
- package/views/casa/partials/phase_banner_alpha.njk +0 -8
- package/views/casa/partials/phase_banner_beta.njk +0 -8
- package/views/casa/review/page-block.njk +0 -8
- package/views/casa/review/review.njk +0 -47
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Mark a waypoint as skipped
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const lodash_1 = require("lodash");
|
|
8
|
+
const JourneyContext_js_1 = __importDefault(require("../lib/JourneyContext.js"));
|
|
9
|
+
const waypoint_url_js_1 = __importDefault(require("../lib/waypoint-url.js"));
|
|
10
|
+
const logger_js_1 = __importDefault(require("../lib/logger.js"));
|
|
11
|
+
const log = (0, logger_js_1.default)('middleware:skip-waypoint');
|
|
12
|
+
exports.default = ({ waypoint, mountUrl, }) => [
|
|
13
|
+
(req, res, next) => {
|
|
14
|
+
if (!(0, lodash_1.has)(req.query, 'skipto')) {
|
|
15
|
+
return next();
|
|
16
|
+
}
|
|
17
|
+
const skipTo = String(req.query.skipto);
|
|
18
|
+
// Inject a special `__skipped__` attribute into this waypoint's data
|
|
19
|
+
log.info(`Marking waypoint "${waypoint}" as skipped`);
|
|
20
|
+
req.casa.journeyContext.clearValidationErrorsForPage(waypoint);
|
|
21
|
+
req.casa.journeyContext.setDataForPage(waypoint, {
|
|
22
|
+
__skipped__: true,
|
|
23
|
+
});
|
|
24
|
+
JourneyContext_js_1.default.putContext(req.session, req.casa.journeyContext);
|
|
25
|
+
const redirectUrl = (0, waypoint_url_js_1.default)({
|
|
26
|
+
mountUrl,
|
|
27
|
+
waypoint: skipTo,
|
|
28
|
+
edit: req.editMode,
|
|
29
|
+
editOrigin: req.editOriginUrl,
|
|
30
|
+
journeyContext: req.casa.journeyContext,
|
|
31
|
+
});
|
|
32
|
+
log.debug(`Will redirect to "${redirectUrl}" after skipping "${waypoint}"`);
|
|
33
|
+
req.session.save((err) => {
|
|
34
|
+
if (err) {
|
|
35
|
+
return next(err);
|
|
36
|
+
}
|
|
37
|
+
res.redirect(302, redirectUrl);
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
];
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// This sits in front of all other middleware and prevents the user from
|
|
3
|
+
// "jumping ahead" in the Plan.
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
const waypoint_url_js_1 = __importDefault(require("../lib/waypoint-url.js"));
|
|
9
|
+
const logger_js_1 = __importDefault(require("../lib/logger.js"));
|
|
10
|
+
const log = (0, logger_js_1.default)('middleware:steer-journey');
|
|
11
|
+
/**
|
|
12
|
+
* @param {Object} obj
|
|
13
|
+
* @param {string} obj.waypoint
|
|
14
|
+
* @param {Plan} obj.plan
|
|
15
|
+
* @param {string} obj.mountUrl
|
|
16
|
+
*/
|
|
17
|
+
exports.default = ({ waypoint, plan, mountUrl, }) => [
|
|
18
|
+
(req, res, next) => {
|
|
19
|
+
// If the requested waypoint doesn't exist in the traversed journey, send
|
|
20
|
+
// the user back to the last good waypoint.
|
|
21
|
+
const traversed = plan.traverse(req.casa.journeyContext);
|
|
22
|
+
if (traversed.indexOf(waypoint) === -1) {
|
|
23
|
+
const redirectTo = traversed[traversed.length - 1];
|
|
24
|
+
log.trace(`Attempted to access "${waypoint}" when not in the journey; redirecting to "${redirectTo}"`);
|
|
25
|
+
return res.redirect(302, (0, waypoint_url_js_1.default)({
|
|
26
|
+
waypoint: redirectTo,
|
|
27
|
+
mountUrl,
|
|
28
|
+
journeyContext: req.casa.journeyContext,
|
|
29
|
+
edit: req.casa.editMode,
|
|
30
|
+
editOrigin: req.casa.editOrigin,
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
// difficult: first waypoint on a Plan - how do we determine if there are other plans pointing at this one?
|
|
34
|
+
// and how do we determine if those others are part of a future plan, or a past one?
|
|
35
|
+
// Think we'll have to leave it up to the dev to add the back link for the first page in a Plan.
|
|
36
|
+
// Calculate URL for the "back" link
|
|
37
|
+
const [prevRoute] = plan.traversePrevRoutes(req.casa.journeyContext, {
|
|
38
|
+
startWaypoint: waypoint,
|
|
39
|
+
stopCondition: () => (true), // stop at the first one
|
|
40
|
+
});
|
|
41
|
+
res.locals.casa.journeyPreviousUrl = prevRoute.target ? (0, waypoint_url_js_1.default)({ mountUrl, waypoint: prevRoute.target, routeName: 'prev' }) : undefined;
|
|
42
|
+
next();
|
|
43
|
+
},
|
|
44
|
+
];
|
|
@@ -0,0 +1,76 @@
|
|
|
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
|
+
// Validate the data captured in the journey context
|
|
7
|
+
const JourneyContext_js_1 = __importDefault(require("../lib/JourneyContext.js"));
|
|
8
|
+
const updateContext = ({ waypoint, errors = null, plan, mountUrl, journeyContext, session, }) => {
|
|
9
|
+
// Set validation state
|
|
10
|
+
if (errors === null) {
|
|
11
|
+
journeyContext.clearValidationErrorsForPage(waypoint);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
journeyContext.setValidationErrorsForPage(waypoint, errors);
|
|
15
|
+
}
|
|
16
|
+
// // Update nav context
|
|
17
|
+
// // In most cases, the "next" & "prev" routes will result in the same sequence,
|
|
18
|
+
// // in reverse. But devs do have the option of setting different logic on
|
|
19
|
+
// // these routes, so this is the proper way to do it.
|
|
20
|
+
// const traversedNext = plan.traverseNextRoutes(journeyContext).map(r => r.source);
|
|
21
|
+
// const traversedPrev = plan.traversePrevRoutes(journeyContext, {
|
|
22
|
+
// startWaypoint: traversedNext[traversedNext.length - 1],
|
|
23
|
+
// }).map(r => r.source);
|
|
24
|
+
// journeyContext.setNavigationUrls(mountUrl, traversedNext, 'next');
|
|
25
|
+
// journeyContext.setNavigationUrls(mountUrl, traversedPrev, 'prev');
|
|
26
|
+
// Save to session
|
|
27
|
+
JourneyContext_js_1.default.putContext(session, journeyContext);
|
|
28
|
+
};
|
|
29
|
+
exports.default = ({ waypoint, fields = [], mountUrl, plan, }) => [
|
|
30
|
+
(req, res, next) => {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
let errors = [];
|
|
33
|
+
for (let i = 0, l = fields.length; i < l; i++) {
|
|
34
|
+
const field = fields[i];
|
|
35
|
+
const fieldName = field.name;
|
|
36
|
+
const fieldValue = (_b = (_a = req.casa.journeyContext.data) === null || _a === void 0 ? void 0 : _a[waypoint]) === null || _b === void 0 ? void 0 : _b[fieldName];
|
|
37
|
+
const context = {
|
|
38
|
+
fieldName,
|
|
39
|
+
fieldValue,
|
|
40
|
+
waypoint,
|
|
41
|
+
journeyContext: req.casa.journeyContext,
|
|
42
|
+
};
|
|
43
|
+
if (!field.testConditions(context))
|
|
44
|
+
continue;
|
|
45
|
+
errors = [
|
|
46
|
+
...errors,
|
|
47
|
+
...field.runValidators(fieldValue, context),
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
// Validation passed with no errors
|
|
51
|
+
if (!errors.length) {
|
|
52
|
+
updateContext({
|
|
53
|
+
waypoint,
|
|
54
|
+
session: req.session,
|
|
55
|
+
mountUrl,
|
|
56
|
+
plan,
|
|
57
|
+
journeyContext: req.casa.journeyContext,
|
|
58
|
+
});
|
|
59
|
+
return next();
|
|
60
|
+
}
|
|
61
|
+
// If there are any native errors in the list, we need to bail the request
|
|
62
|
+
if (errors.find((e) => e instanceof Error)) {
|
|
63
|
+
return next(e);
|
|
64
|
+
}
|
|
65
|
+
// Make the errors available to downstream middleware
|
|
66
|
+
updateContext({
|
|
67
|
+
errors,
|
|
68
|
+
waypoint,
|
|
69
|
+
session: req.session,
|
|
70
|
+
mountUrl,
|
|
71
|
+
plan,
|
|
72
|
+
journeyContext: req.casa.journeyContext,
|
|
73
|
+
});
|
|
74
|
+
next();
|
|
75
|
+
}
|
|
76
|
+
];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Basic wrapper to act as the package entrypoint for ESM applications
|
|
2
|
+
// ref: https://redfin.engineering/node-modules-at-war-why-commonjs-and-es-modules-cant-get-along-9617135eeca1
|
|
3
|
+
import casa from '../casa.js';
|
|
4
|
+
export const configure = casa.configure;
|
|
5
|
+
export const validators = casa.validators;
|
|
6
|
+
export const field = casa.field;
|
|
7
|
+
export const Plan = casa.Plan;
|
|
8
|
+
export const JourneyContext = casa.JourneyContext;
|
|
9
|
+
export const ValidationError = casa.ValidationError;
|
|
10
|
+
export const waypointUrl = casa.waypointUrl;
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
+
const MutableRouter_js_1 = __importDefault(require("../lib/MutableRouter.js"));
|
|
7
|
+
function ancillaryRouter({ sessionTtl, }) {
|
|
8
|
+
// Router
|
|
9
|
+
const router = new MutableRouter_js_1.default();
|
|
10
|
+
// Session timeout
|
|
11
|
+
// TODO: add a `ancillary.presessiontimeout` hook here? Might be useful for those who way to enhance the timeout route, rather than replacing it completely
|
|
12
|
+
router.all('/session-timeout', (req, res) => {
|
|
13
|
+
res.render('casa/session-timeout.njk', {
|
|
14
|
+
sessionTtl: Math.floor(sessionTtl / 60),
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
return router;
|
|
18
|
+
}
|
|
19
|
+
exports.default = ancillaryRouter;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = __dirname;
|
|
@@ -0,0 +1,130 @@
|
|
|
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
|
+
/* eslint-disable object-curly-newline,max-len */
|
|
7
|
+
const MutableRouter_js_1 = __importDefault(require("../lib/MutableRouter.js"));
|
|
8
|
+
const skip_waypoint_js_1 = __importDefault(require("../middleware/skip-waypoint.js"));
|
|
9
|
+
const steer_journey_js_1 = __importDefault(require("../middleware/steer-journey.js"));
|
|
10
|
+
const sanitise_fields_js_1 = __importDefault(require("../middleware/sanitise-fields.js"));
|
|
11
|
+
const gather_fields_js_1 = __importDefault(require("../middleware/gather-fields.js"));
|
|
12
|
+
const validate_fields_js_1 = __importDefault(require("../middleware/validate-fields.js"));
|
|
13
|
+
const progress_journey_js_1 = __importDefault(require("../middleware/progress-journey.js"));
|
|
14
|
+
const waypoint_url_js_1 = __importDefault(require("../lib/waypoint-url.js"));
|
|
15
|
+
const logger_js_1 = __importDefault(require("../lib/logger.js"));
|
|
16
|
+
const log = (0, logger_js_1.default)('router:journey');
|
|
17
|
+
const resolveHooks = (hookName, waypoint, pageHooks, globalHooks = []) => {
|
|
18
|
+
const waypointPath = `/${waypoint}`;
|
|
19
|
+
const pathMatch = (h) => h.path === undefined || (h.path instanceof RegExp && h.path.test(waypointPath)) || h.path === waypointPath;
|
|
20
|
+
const matchedPageHooks = (pageHooks || []).filter((h) => `journey.${h.hook}` === hookName).map((h) => h.middleware);
|
|
21
|
+
const matchedGlobalHooks = globalHooks.filter((h) => h.hook === hookName).filter(pathMatch).map((h) => h.middleware);
|
|
22
|
+
return [
|
|
23
|
+
...matchedGlobalHooks,
|
|
24
|
+
...matchedPageHooks,
|
|
25
|
+
];
|
|
26
|
+
};
|
|
27
|
+
const renderMiddlewareFactory = (view, contextFactory) => [
|
|
28
|
+
(req, res, next) => {
|
|
29
|
+
res.render(view, Object.assign({
|
|
30
|
+
// Common template variables for both GET and POST requests
|
|
31
|
+
inEditMode: req.casa.editMode, editOriginUrl: req.casa.editOrigin,
|
|
32
|
+
// editSearchParams: req.editSearchParams,
|
|
33
|
+
activeContextId: req.casa.journeyContext.identity.id }, contextFactory(req)), (err, templateString) => {
|
|
34
|
+
if (err) {
|
|
35
|
+
// logger.error(err);
|
|
36
|
+
next(err);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
res.send(templateString);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
function journeyRouter({ globalHooks, pages, plan, csrfMiddleware, mountUrl, }) {
|
|
45
|
+
// Router
|
|
46
|
+
const router = new MutableRouter_js_1.default();
|
|
47
|
+
// Special "_" route which handles redirecting the user between sub-apps
|
|
48
|
+
// /app1/_/?refmount=app2&route=prev
|
|
49
|
+
// - will redirect to the
|
|
50
|
+
router.all('/_', (req, res) => {
|
|
51
|
+
var _a, _b;
|
|
52
|
+
const refmount = (_a = req.query) === null || _a === void 0 ? void 0 : _a.refmount;
|
|
53
|
+
const route = (_b = req.query) === null || _b === void 0 ? void 0 : _b.route;
|
|
54
|
+
log.trace(`App root ${mountUrl}: refmount = ${refmount}, route = ${route}`);
|
|
55
|
+
let redirectTo;
|
|
56
|
+
const fallback = (0, waypoint_url_js_1.default)({
|
|
57
|
+
mountUrl,
|
|
58
|
+
waypoint: plan.traverse(req.casa.journeyContext, {
|
|
59
|
+
stopCondition: () => (true), // we only need one; stop at the first
|
|
60
|
+
})[0],
|
|
61
|
+
});
|
|
62
|
+
if (route === 'prev') {
|
|
63
|
+
const routes = plan.traversePrevRoutes(req.casa.journeyContext, { startWaypoint: refmount });
|
|
64
|
+
redirectTo = routes.length ? (0, waypoint_url_js_1.default)({ mountUrl, waypoint: routes[0].target }) : fallback;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
const routes = plan.traverseNextRoutes(req.casa.journeyContext, { startWaypoint: refmount });
|
|
68
|
+
if (routes[0].target !== null) {
|
|
69
|
+
redirectTo = routes.length ? (0, waypoint_url_js_1.default)({ mountUrl, waypoint: routes[0].target }) : fallback;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
redirectTo = fallback;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Carry over any params
|
|
76
|
+
const url = new URL(redirectTo, 'https://placeholder.test/');
|
|
77
|
+
const searchParams = new URLSearchParams(req.query);
|
|
78
|
+
searchParams.delete('refmount');
|
|
79
|
+
searchParams.delete('route');
|
|
80
|
+
url.search = searchParams.toString();
|
|
81
|
+
redirectTo = `${url.pathname.replace(/\/+/g, '/')}${url.search}`;
|
|
82
|
+
log.trace(`Redirect to ${redirectTo}`);
|
|
83
|
+
return res.redirect(redirectTo);
|
|
84
|
+
});
|
|
85
|
+
// Create GET / POST routes for each page
|
|
86
|
+
const commonMiddleware = [
|
|
87
|
+
...csrfMiddleware,
|
|
88
|
+
];
|
|
89
|
+
pages.forEach((page) => {
|
|
90
|
+
const { waypoint, view, hooks: pageHooks, fields } = page;
|
|
91
|
+
const formUrl = (0, waypoint_url_js_1.default)({ mountUrl, waypoint });
|
|
92
|
+
const waypointPath = `/${waypoint}`;
|
|
93
|
+
const commonWaypointMiddleware = [
|
|
94
|
+
(req, res, next) => {
|
|
95
|
+
req.casa.waypoint = waypoint;
|
|
96
|
+
next();
|
|
97
|
+
},
|
|
98
|
+
...(0, skip_waypoint_js_1.default)({ mountUrl, waypoint }),
|
|
99
|
+
];
|
|
100
|
+
router.get(waypointPath, ...commonMiddleware, ...commonWaypointMiddleware, ...resolveHooks('journey.presteer', waypoint, pageHooks, globalHooks), ...(0, steer_journey_js_1.default)({ waypoint, mountUrl, plan }), ...resolveHooks('journey.poststeer', waypoint, pageHooks, globalHooks), ...resolveHooks('journey.prerender', waypoint, pageHooks, globalHooks), renderMiddlewareFactory(view, (req) => ({
|
|
101
|
+
formUrl,
|
|
102
|
+
formData: req.casa.journeyContext.getDataForPage(waypoint),
|
|
103
|
+
})));
|
|
104
|
+
router.post(waypointPath, ...commonMiddleware, ...commonWaypointMiddleware, ...resolveHooks('journey.presteer', waypoint, pageHooks, globalHooks), ...(0, steer_journey_js_1.default)({ waypoint, mountUrl, plan }), ...resolveHooks('journey.poststeer', waypoint, pageHooks, globalHooks), ...resolveHooks('journey.presanitise', waypoint, pageHooks, globalHooks), ...(0, sanitise_fields_js_1.default)({ waypoint, fields }), ...resolveHooks('journey.postsanitise', waypoint, pageHooks, globalHooks), ...resolveHooks('journey.pregather', waypoint, pageHooks, globalHooks), ...(0, gather_fields_js_1.default)({ waypoint, fields }), ...resolveHooks('journey.postgather', waypoint, pageHooks, globalHooks), ...resolveHooks('journey.prevalidate', waypoint, pageHooks, globalHooks), ...(0, validate_fields_js_1.default)({ waypoint, fields, mountUrl, plan }), ...resolveHooks('journey.postvalidate', waypoint, pageHooks, globalHooks),
|
|
105
|
+
// If there were validation errors, jump out of this route and into the
|
|
106
|
+
// next, where the errors will be rendered
|
|
107
|
+
(req, res, next) => (req.casa.journeyContext.hasValidationErrorsForPage(waypoint) ? next('route') : next()), ...resolveHooks('journey.preredirect', waypoint, pageHooks, globalHooks), ...(0, progress_journey_js_1.default)({ waypoint, plan, mountUrl }));
|
|
108
|
+
router.post(waypointPath, ...resolveHooks('journey.prerender', waypoint, pageHooks, globalHooks), renderMiddlewareFactory(view, (req) => {
|
|
109
|
+
var _a;
|
|
110
|
+
const errors = (_a = req.casa.journeyContext.getValidationErrorsForPageByField(waypoint)) !== null && _a !== void 0 ? _a : Object.create(null);
|
|
111
|
+
// This is a convenience for the template. The `govukErrorSummary` macro
|
|
112
|
+
// requires the errors be in a particular format, so here we provide our
|
|
113
|
+
// errors in that format.
|
|
114
|
+
// Where there are multiple errors against a particular field, only the
|
|
115
|
+
// first one is shown.
|
|
116
|
+
const govukErrors = Object.keys(errors).map((k) => ({
|
|
117
|
+
text: req.t(errors[k][0].summary, errors[k][0].variables),
|
|
118
|
+
href: errors[k][0].fieldHref,
|
|
119
|
+
}));
|
|
120
|
+
return {
|
|
121
|
+
formUrl,
|
|
122
|
+
formData: req.body,
|
|
123
|
+
formErrors: Object.keys(errors).length ? errors : null,
|
|
124
|
+
formErrorsGovukArray: govukErrors.length ? govukErrors : null,
|
|
125
|
+
};
|
|
126
|
+
}));
|
|
127
|
+
});
|
|
128
|
+
return router;
|
|
129
|
+
}
|
|
130
|
+
exports.default = journeyRouter;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} StaticOptions Options to configure static router
|
|
3
|
+
* @property {string} [mountUrl=/] URL prefix for govuk-frontend static assets (optional, default /)
|
|
4
|
+
* @property {number} [maxAge=3600000] Cache TTL for all assets (optional, default 1 hour)
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Create a router for serving CASA's static assets.
|
|
8
|
+
*
|
|
9
|
+
* @param {StaticOptions} options Options
|
|
10
|
+
* @returns {MutableRouter} ExpressJS Router instance
|
|
11
|
+
*/
|
|
12
|
+
export default function staticRouter({ mountUrl, maxAge, }: StaticOptions): MutableRouter;
|
|
13
|
+
/**
|
|
14
|
+
* Options to configure static router
|
|
15
|
+
*/
|
|
16
|
+
export type StaticOptions = {
|
|
17
|
+
/**
|
|
18
|
+
* )
|
|
19
|
+
*/
|
|
20
|
+
mountUrl?: string | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Cache TTL for all assets (optional, default 1 hour)
|
|
23
|
+
*/
|
|
24
|
+
maxAge?: number | undefined;
|
|
25
|
+
};
|
|
26
|
+
import MutableRouter from "../lib/MutableRouter.js";
|
|
@@ -0,0 +1,67 @@
|
|
|
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
|
+
const express_1 = require("express");
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const url_1 = require("url");
|
|
9
|
+
const path_1 = require("path");
|
|
10
|
+
const module_1 = require("module");
|
|
11
|
+
const dirname_cjs_1 = __importDefault(require("./dirname.cjs"));
|
|
12
|
+
const MutableRouter_js_1 = __importDefault(require("../lib/MutableRouter.js"));
|
|
13
|
+
const oneDay = 86400000;
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {object} StaticOptions Options to configure static router
|
|
16
|
+
* @property {string} [mountUrl=/] URL prefix for govuk-frontend static assets (optional, default /)
|
|
17
|
+
* @property {number} [maxAge=3600000] Cache TTL for all assets (optional, default 1 hour)
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Create a router for serving CASA's static assets.
|
|
21
|
+
*
|
|
22
|
+
* @param {StaticOptions} options Options
|
|
23
|
+
* @returns {MutableRouter} ExpressJS Router instance
|
|
24
|
+
*/
|
|
25
|
+
function staticRouter({ mountUrl = '/', maxAge = 3600000, }) {
|
|
26
|
+
const staticRouter = new MutableRouter_js_1.default();
|
|
27
|
+
const notFoundHandler = (req, res, next) => {
|
|
28
|
+
// Fall through to a general purpose error handler
|
|
29
|
+
next(new Error('404'));
|
|
30
|
+
};
|
|
31
|
+
const setHeaders = (req, res, next) => {
|
|
32
|
+
var _a;
|
|
33
|
+
res.set('cache-control', 'public');
|
|
34
|
+
res.set('pragma', 'cache');
|
|
35
|
+
res.set('expires', new Date(Date.now() + oneDay).toUTCString());
|
|
36
|
+
const { pathname } = new url_1.URL((_a = req === null || req === void 0 ? void 0 : req.originalUrl) !== null && _a !== void 0 ? _a : '', 'http://placeholder.test/');
|
|
37
|
+
if (pathname.substr(-4) === '.css') {
|
|
38
|
+
// Just needed for our in-memory CSS assets
|
|
39
|
+
res.set('content-type', 'text/css');
|
|
40
|
+
}
|
|
41
|
+
next();
|
|
42
|
+
};
|
|
43
|
+
const staticConfig = {
|
|
44
|
+
etag: true,
|
|
45
|
+
lastModified: false,
|
|
46
|
+
maxAge,
|
|
47
|
+
setHeaders: (res) => {
|
|
48
|
+
setHeaders(null, res, () => { });
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
// The CASA CSS source contains the placeholder `~~~CASA_MOUNT_URL~~~` which
|
|
52
|
+
// must be replaced with the dynamic `mountUrl` to ensure govuk-frontend
|
|
53
|
+
// assets are served from the correct location.
|
|
54
|
+
const casaCss = (0, fs_1.readFileSync)((0, path_1.resolve)(dirname_cjs_1.default, '../../dist/assets/css/casa.css'), { encoding: 'utf8' }).replace(/~~~CASA_MOUNT_URL~~~/g, mountUrl);
|
|
55
|
+
const casaCssIe8 = (0, fs_1.readFileSync)((0, path_1.resolve)(dirname_cjs_1.default, '../../dist/assets/css/casa-ie8.css'), { encoding: 'utf8' }).replace(/~~~CASA_MOUNT_URL~~~/g, mountUrl);
|
|
56
|
+
// The static middleware will only server GET/HEAD requests, so we can mount
|
|
57
|
+
// the middleware using `use()` rather than resorting to `get()`
|
|
58
|
+
const govukFrontendDirectory = (0, path_1.resolve)((0, module_1.createRequire)(dirname_cjs_1.default).resolve('govuk-frontend'), '../../');
|
|
59
|
+
staticRouter.use('/govuk/assets/js/all.js', (0, express_1.static)(`${govukFrontendDirectory}/govuk/all.js`, staticConfig));
|
|
60
|
+
staticRouter.use('/govuk/assets', (0, express_1.static)(`${govukFrontendDirectory}/govuk/assets`, staticConfig));
|
|
61
|
+
staticRouter.use('/govuk/assets', notFoundHandler);
|
|
62
|
+
staticRouter.use('/casa/assets/css/casa.css', setHeaders, (req, res) => res.send(casaCss));
|
|
63
|
+
staticRouter.use('/casa/assets/css/casa-ie8.css', setHeaders, (req, res) => res.send(casaCssIe8));
|
|
64
|
+
staticRouter.use('/casa/assets', notFoundHandler);
|
|
65
|
+
return staticRouter;
|
|
66
|
+
}
|
|
67
|
+
exports.default = staticRouter;
|
package/package.json
CHANGED
|
@@ -1,110 +1,69 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dwp/govuk-casa",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
5
|
-
"main": "casa.js",
|
|
3
|
+
"version": "8.0.0-alpha1",
|
|
4
|
+
"description": "A framework for building GOVUK Collect-And-Submit-Applications",
|
|
5
|
+
"main": "dist/casa.js",
|
|
6
|
+
"module": "dist/mjs/casa.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
"import": "./dist/mjs/esm-wrapper.js",
|
|
9
|
+
"require": "./dist/casa.js"
|
|
10
|
+
},
|
|
11
|
+
"typings": "dist/casa.d.ts",
|
|
6
12
|
"files": [
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"/locales/**/*",
|
|
11
|
-
"/middleware/**/*",
|
|
12
|
-
"/test/utils/**/*",
|
|
13
|
-
"/src/scss/*",
|
|
14
|
-
"/src/browserconfig.xml",
|
|
15
|
-
"/views/**/*",
|
|
16
|
-
"/index.js",
|
|
17
|
-
"/casa.js",
|
|
18
|
-
"/**/*.d.ts",
|
|
19
|
-
"!/**/*/.DS_Store",
|
|
20
|
-
"!/**/*/.gitkeep",
|
|
21
|
-
"!/examples/**/*",
|
|
22
|
-
"!/test/unit/testdata/**/*"
|
|
13
|
+
"dist/**/*",
|
|
14
|
+
"locales/**/*",
|
|
15
|
+
"views/**/*"
|
|
23
16
|
],
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
17
|
+
"scripts": {
|
|
18
|
+
"test": "mocha './tests/**/*.test.js'",
|
|
19
|
+
"test:e2e": "spiderplan --worker-init ./tests/e2e/worker-init.js --language en ./tests/e2e/personas/**/*.yaml",
|
|
20
|
+
"build": "npm run build:prepare && npm run build:sources && npm run build:css-assets",
|
|
21
|
+
"build:prepare": "rm -rf dist/* && mkdir -p dist/assets/js/ && mkdir -p dist/assets/css/",
|
|
22
|
+
"build:sources": "tsc -p tsconfig-cjs.json && ./scripts/fixup.sh",
|
|
23
|
+
"build:css-assets": "node scripts/compile-sass.js",
|
|
24
|
+
"prepare": "npm run build"
|
|
30
25
|
},
|
|
26
|
+
"keywords": [],
|
|
27
|
+
"author": "DWP Digital",
|
|
28
|
+
"license": "ISC",
|
|
29
|
+
"type": "module",
|
|
31
30
|
"dependencies": {
|
|
32
|
-
"
|
|
33
|
-
"colors": "1.4.0",
|
|
31
|
+
"cookie-parser": "1.4.5",
|
|
34
32
|
"csurf": "1.11.0",
|
|
35
33
|
"debug": "4.3.2",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"govuk-frontend": "3.
|
|
40
|
-
"govuk_template_jinja": "0.26.0",
|
|
34
|
+
"deepmerge": "4.2.2",
|
|
35
|
+
"express": "4.17.1",
|
|
36
|
+
"express-session": "1.17.2",
|
|
37
|
+
"govuk-frontend": "3.14.0",
|
|
41
38
|
"graphlib": "2.1.8",
|
|
42
|
-
"
|
|
43
|
-
"
|
|
39
|
+
"helmet": "4.6.0",
|
|
40
|
+
"i18next": "21.2.4",
|
|
41
|
+
"i18next-http-middleware": "3.1.4",
|
|
42
|
+
"js-yaml": "4.1.0",
|
|
43
|
+
"lodash": "4.17.21",
|
|
44
44
|
"luxon": "2.0.2",
|
|
45
45
|
"nunjucks": "3.2.3",
|
|
46
|
-
"serve-favicon": "2.5.0",
|
|
47
|
-
"uid-safe": "2.1.5",
|
|
48
46
|
"uuid": "8.3.2",
|
|
49
|
-
"validator": "13.6.0"
|
|
47
|
+
"validator": "^13.6.0"
|
|
50
48
|
},
|
|
51
49
|
"devDependencies": {
|
|
52
|
-
"@
|
|
53
|
-
"@
|
|
54
|
-
"@
|
|
50
|
+
"@babel/core": "7.15.8",
|
|
51
|
+
"@babel/eslint-parser": "7.15.8",
|
|
52
|
+
"@babel/preset-env": "7.15.8",
|
|
53
|
+
"@dwp/casa-spiderplan": "1.0.0",
|
|
55
54
|
"@dwp/commitlint-config-base": "1.2.0",
|
|
56
55
|
"@dwp/eslint-config-base": "5.0.1",
|
|
57
|
-
"@
|
|
58
|
-
"@
|
|
59
|
-
"
|
|
60
|
-
"@stryker-mutator/mocha-framework": "4.0.0",
|
|
61
|
-
"@stryker-mutator/mocha-runner": "5.4.0",
|
|
62
|
-
"autocannon": "7.4.0",
|
|
56
|
+
"@types/express": "4.17.13",
|
|
57
|
+
"@types/node": "16.10.2",
|
|
58
|
+
"babel-eslint": "10.1.0",
|
|
63
59
|
"chai": "4.3.4",
|
|
64
|
-
"
|
|
65
|
-
"chai-http": "4.3.0",
|
|
66
|
-
"cheerio": "1.0.0-rc.10",
|
|
67
|
-
"conventional-changelog-cli": "2.1.1",
|
|
60
|
+
"commitlint": "13.2.0",
|
|
68
61
|
"eslint": "7.32.0",
|
|
69
62
|
"eslint-plugin-no-unsafe-regex": "1.0.0",
|
|
70
63
|
"eslint-plugin-sonarjs": "0.10.0",
|
|
71
|
-
"express": "4.17.1",
|
|
72
|
-
"express-session": "1.17.2",
|
|
73
64
|
"husky": "7.0.2",
|
|
74
|
-
"jsdom": "17.0.0",
|
|
75
|
-
"minimatch": "3.0.4",
|
|
76
65
|
"mocha": "9.1.2",
|
|
77
|
-
"nyc": "15.1.0",
|
|
78
|
-
"proxyquire": "2.1.3",
|
|
79
66
|
"sass": "1.42.1",
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
"supertest": "6.1.6",
|
|
83
|
-
"uglify-js": "3.14.2",
|
|
84
|
-
"yargs": "17.2.1"
|
|
85
|
-
},
|
|
86
|
-
"peerDependencies": {
|
|
87
|
-
"express": "4.x",
|
|
88
|
-
"express-session": "1.x"
|
|
89
|
-
},
|
|
90
|
-
"scripts": {
|
|
91
|
-
"pipeline": "npm test && npm run compliance && npm run quality && npm run security:vulnerable-packages && (npm outdated || true)",
|
|
92
|
-
"compliance": "npm run compliance:lint",
|
|
93
|
-
"compliance:lint": "eslint .",
|
|
94
|
-
"test": "npm run test:unit --silent && npm run test:integration --silent",
|
|
95
|
-
"test:unit": "mocha -R spec \"./test/unit/**/*.test.js\"",
|
|
96
|
-
"test:integration": "mocha -R spec \"./test/integration/**/*.test.js\"",
|
|
97
|
-
"test:performance": "node ./test/performance/plan.test.js",
|
|
98
|
-
"quality": "npm run quality:coverage",
|
|
99
|
-
"quality:coverage": "nyc npm test",
|
|
100
|
-
"quality:mutation": "stryker run",
|
|
101
|
-
"security": "npm run security:vulnerable-packages",
|
|
102
|
-
"security:vulnerable-packages": "npm audit --production --registry=https://registry.npmjs.org --json | node -e 'a=JSON.parse(fs.readFileSync(\"/dev/stdin\",\"utf-8\")).metadata.vulnerabilities;process.exit(a.high+a.critical);'",
|
|
103
|
-
"package:changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
|
|
104
|
-
"compile-static-assets": "node ./scripts/compile-sass.js && node ./scripts/compile-js.js",
|
|
105
|
-
"prepare": "npm run compile-static-assets --silent; husky install",
|
|
106
|
-
"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"
|
|
107
|
-
},
|
|
108
|
-
"author": "DWP <open-source@engineering.digital.dwp.gov.uk>",
|
|
109
|
-
"license": "ISC"
|
|
67
|
+
"typescript": "4.4.3"
|
|
68
|
+
}
|
|
110
69
|
}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
id: params.id if params.id else 'f-' + params.name + '-wrapper' | safe
|
|
17
17
|
}) %}
|
|
18
18
|
|
|
19
|
+
|
|
19
20
|
{# Add checked flag to chosen inputs #}
|
|
20
21
|
{% set mergedItems = [] %}
|
|
21
22
|
{% for item in params.items %}
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
{% set mergedItems = (mergedItems.push(item), mergedItems) %}
|
|
31
32
|
{% endfor %}
|
|
32
33
|
|
|
34
|
+
|
|
33
35
|
{# Merge parameters #}
|
|
34
36
|
{% set mergedParams = mergeObjects(params, {
|
|
35
37
|
name: fieldName,
|
|
@@ -43,11 +45,12 @@
|
|
|
43
45
|
|
|
44
46
|
{# Ensure that the first item has the id matching `f-<name>` in order for error summary linkage to work #}
|
|
45
47
|
{% if not mergedParams.items[0].id %}
|
|
46
|
-
{% set mergedParams =
|
|
48
|
+
{% set mergedParams = mergeObjects(mergedParams, {
|
|
47
49
|
items: [{
|
|
48
50
|
id: 'f-' + params.name
|
|
49
51
|
}]
|
|
50
52
|
}) %}
|
|
51
53
|
{% endif %}
|
|
52
54
|
|
|
55
|
+
|
|
53
56
|
{{ govukCheckboxes(mergedParams) }}
|