hof 20.0.0-beta.16 → 20.0.0-beta.19

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # HOF (Home Office Forms)
2
+
2
3
  [![NPM_Publish Actions Status](https://github.com/UKHomeOfficeForms/hof/workflows/Automate_Publish/badge.svg)](https://github.com/UKHomeOfficeForms/hof/actions)
3
4
  [![npm version](https://badge.fury.io/js/hof.svg)](https://badge.fury.io/js/hof)
4
5
  [![Known Vulnerabilities](https://snyk.io/test/npm/hof/badge.svg)](https://snyk.io/test/npm/hof)
@@ -6,6 +7,7 @@
6
7
  HOF (Home Office Forms) is a framework designed to assist developers in creating form-based workflows in a rapid, repeatable and secure way. It aims to reduce simple applications as much as possible to being configuration-only.
7
8
 
8
9
  ## Server Settings
10
+
9
11
  In your `hof.settings.json` file you can add `getTerms: false` and `getCookies: false` to turn off the default cookies, and terms and conditions information provided by the HOF framework. This is if you want to provide more specific material at the service level in regards to these subject matter otherwise the defaults should suffice.
10
12
 
11
13
  Also you can set `getAccessibility: true` to get the default accessibility document for this framework if one is not provided at the service level. It is assumed there should have been an accessibility audit carried out for a service already hence why the default setting for this is set to `false`. But if a generic placeholder is needed to ensure the service is legally compliant then this can be set to `true` to provide the default one presented within the framework.
@@ -17,9 +19,11 @@ Also you can set `getAccessibility: true` to get the default accessibility docum
17
19
  [https://ukhomeofficeforms.github.io/hof-guide/](https://ukhomeofficeforms.github.io/hof-guide/)
18
20
 
19
21
  ## Content Security Policy
22
+
20
23
  ### Inline JavaScript from 18.0.0
24
+
21
25
  From version 18.0.0, unsafe-inline has been removed from the content security policy by default. This means scripts
22
- must either be referenced using the src attribute, ```<script src='...'></script>``` or with a nonce value attribute. A nonce
26
+ must either be referenced using the src attribute, `<script src='...'></script>` or with a nonce value attribute. A nonce
23
27
  value is generated for every request. You can add this to your own templates' inline scripts as needed:
24
28
 
25
29
  ```
@@ -29,15 +33,17 @@ value is generated for every request. You can add this to your own templates' in
29
33
  ```
30
34
 
31
35
  ### Built with HOF
32
- * https://github.com/UKHomeOffice/gro
33
- * https://github.com/UKHomeOffice/end-tenancy
34
- * [Firearms Licensing (Home Office)](https://github.com/UKHomeOffice/firearms)
35
- * [Contact UK Trade & Investment (UK Trade & Investment)](https://github.com/UKTradeInvestment/contact-ukti)
36
- * [Biometric Residence Permit (Home Office)](https://github.com/UKHomeOffice/brp_app)
37
- * [Report terrorist material (Home Office)](https://github.com/UKHomeOffice/rotm)
38
- * [UKVI Complaints (Home Office)](https://github.com/UKHomeOffice/Complaints)
36
+
37
+ - https://github.com/UKHomeOffice/gro
38
+ - https://github.com/UKHomeOffice/end-tenancy
39
+ - [Firearms Licensing (Home Office)](https://github.com/UKHomeOffice/firearms)
40
+ - [Contact UK Trade & Investment (UK Trade & Investment)](https://github.com/UKTradeInvestment/contact-ukti)
41
+ - [Biometric Residence Permit (Home Office)](https://github.com/UKHomeOffice/brp_app)
42
+ - [Report terrorist material (Home Office)](https://github.com/UKHomeOffice/rotm)
43
+ - [UKVI Complaints (Home Office)](https://github.com/UKHomeOffice/Complaints)
39
44
 
40
45
  ## HOF BUILD
46
+
41
47
  Performs build workflow for hof apps in prod and development
42
48
 
43
49
  ## Usage
@@ -54,10 +60,10 @@ It is recommended to alias `hof-build` to an npm script in your package.json.
54
60
 
55
61
  ## Tasks
56
62
 
57
- * `browserify` - compiles client-side js with browserify
58
- * `sass` - compiles sass
59
- * `images` - copies images from ./assets/images directory to ./public/images
60
- * `translate` - compiles translation files
63
+ - `browserify` - compiles client-side js with browserify
64
+ - `sass` - compiles sass
65
+ - `images` - copies images from ./assets/images directory to ./public/images
66
+ - `translate` - compiles translation files
61
67
 
62
68
  ## Watch
63
69
 
@@ -98,7 +104,7 @@ Any task can be disabled by setting its configuration to `false` (or any falsy v
98
104
 
99
105
  ```js
100
106
  module.exports = {
101
- browserify: false
107
+ browserify: false,
102
108
  };
103
109
  ```
104
110
 
@@ -106,15 +112,15 @@ module.exports = {
106
112
 
107
113
  Each task has a common configuration format with the following options:
108
114
 
109
- * `src` - defines the input file or files for the build task
110
- * `out` - defines the output location of the built code where relevant
111
- * `match` - defines the pattern for files to watch to trigger a rebuild of this task
112
- * `restart` - defines if this task should result in a server restart
115
+ - `src` - defines the input file or files for the build task
116
+ - `out` - defines the output location of the built code where relevant
117
+ - `match` - defines the pattern for files to watch to trigger a rebuild of this task
118
+ - `restart` - defines if this task should result in a server restart
113
119
 
114
120
  Additionally the server instance created by `watch` can be configured by setting `server` config. Available options are:
115
121
 
116
- * `cmd` - defines the command used to start the server
117
- * `extensions` - defines the file extensions which will be watched to trigger a restart
122
+ - `cmd` - defines the command used to start the server
123
+ - `extensions` - defines the file extensions which will be watched to trigger a restart
118
124
 
119
125
  ### Shared Translations
120
126
 
@@ -123,6 +129,7 @@ By default translations put in the commons directory in a HOF project, i.e. `app
123
129
  To override this behaviour you can add the following to your `hof.settings.json` file or to the settings possible to hof on your server.js file
124
130
 
125
131
  Hof.settings.json example
132
+
126
133
  ```
127
134
  "build": {
128
135
  "translate": {
@@ -132,6 +139,7 @@ Hof.settings.json example
132
139
  ```
133
140
 
134
141
  server.js example
142
+
135
143
  ```
136
144
  const hof = require('hof');
137
145
  const settings = { ...behaviours, ...routes };
@@ -155,9 +163,10 @@ hof-transpiler [source dir|glob] {OPTIONS}
155
163
 
156
164
  ## Example
157
165
 
158
- Lets say you have a directory such as: ```translations/src/en```
166
+ Lets say you have a directory such as: `translations/src/en`
159
167
 
160
168
  Which contains:
169
+
161
170
  ```
162
171
  buttons.json
163
172
  emails.json
@@ -165,9 +174,9 @@ errors.json
165
174
  validation.json
166
175
  ```
167
176
 
168
- If you run hof-transpiler against the directory ```hof-transpiler ./translations/src```
177
+ If you run hof-transpiler against the directory `hof-transpiler ./translations/src`
169
178
 
170
- It will iterate through src and for each directory it will create a new directory at the root level with a built default.json file ```translations/en/default.json```
179
+ It will iterate through src and for each directory it will create a new directory at the root level with a built default.json file `translations/en/default.json`
171
180
 
172
181
  Which will look something like
173
182
 
@@ -192,26 +201,30 @@ This is used further down the hof stack for application translations.
192
201
 
193
202
  ## Advanced example - duplicate keys between source folder and shared folder
194
203
 
195
- Lets say you have a directory such as: ```translations/src/en```
204
+ Lets say you have a directory such as: `translations/src/en`
196
205
 
197
206
  Which contains:
198
207
  buttons.json containing:
208
+
199
209
  ```json
200
210
  {
201
211
  "unusual-button": "Moo"
202
212
  }
203
213
  ```
214
+
204
215
  emails.json containing:
216
+
205
217
  ```json
206
218
  {
207
219
  "customer-email": "Hi how are you?"
208
220
  }
209
221
  ```
210
222
 
211
- And you also have a directory of shared translations such as: ```shared-translations/src/en```
223
+ And you also have a directory of shared translations such as: `shared-translations/src/en`
212
224
 
213
225
  Which contains:
214
226
  buttons.json containing:
227
+
215
228
  ```json
216
229
  {
217
230
  "common-button": "Click me"
@@ -219,11 +232,13 @@ buttons.json containing:
219
232
  ```
220
233
 
221
234
  If you then run:
235
+
222
236
  ```bash
223
237
  hof-transpiler translations/src --shared shared-translations/src
224
238
  ```
225
239
 
226
240
  Then transpiled translations should appear in translations/en/default.json as follows:
241
+
227
242
  ```json
228
243
  {
229
244
  "buttons": {
@@ -245,6 +260,7 @@ hof-transpiler supports multiple shared sources, extending them from left to rig
245
260
  If you have the following sources:
246
261
 
247
262
  node_modules/hof-template-partials/translations/src/en/buttons.json
263
+
248
264
  ```json
249
265
  {
250
266
  "continue": "Continue",
@@ -255,6 +271,7 @@ node_modules/hof-template-partials/translations/src/en/buttons.json
255
271
  ```
256
272
 
257
273
  common/translations/src/en/buttons.json
274
+
258
275
  ```json
259
276
  {
260
277
  "skip": "Skip this step",
@@ -263,6 +280,7 @@ common/translations/src/en/buttons.json
263
280
  ```
264
281
 
265
282
  my-application/translations/src/en/buttons.json
283
+
266
284
  ```json
267
285
  {
268
286
  "continue": "Go Forth!"
@@ -270,11 +288,13 @@ my-application/translations/src/en/buttons.json
270
288
  ```
271
289
 
272
290
  If you then run:
291
+
273
292
  ```bash
274
293
  hof-transpiler my-application/translations/src --shared node_modules/hof-template-partials/translations/src --shared common/translations/src
275
294
  ```
276
295
 
277
296
  my-application/translations/en/default.json
297
+
278
298
  ```json
279
299
  {
280
300
  "buttons": {
@@ -286,6 +306,7 @@ my-application/translations/en/default.json
286
306
  }
287
307
  }
288
308
  ```
309
+
289
310
  #HOF Controller
290
311
 
291
312
  Implements a request pipeline for GET and POST of forms, with input cleaning/formatting and validation.
@@ -295,18 +316,18 @@ Implements a request pipeline for GET and POST of forms, with input cleaning/for
295
316
  Basic usage:
296
317
 
297
318
  ```javascript
298
- var Form = require('./controller');
319
+ var Form = require("./controller");
299
320
 
300
321
  var form = new Form({
301
- template: 'form',
302
- fields: {
303
- name: {
304
- validate: 'required'
305
- }
306
- }
322
+ template: "form",
323
+ fields: {
324
+ name: {
325
+ validate: "required",
326
+ },
327
+ },
307
328
  });
308
329
 
309
- app.use('/', form.requestHandler());
330
+ app.use("/", form.requestHandler());
310
331
  ```
311
332
 
312
333
  This won't really be very useful though, since all it will do is render the "form" template on `/` and respond to GET and POST requests.
@@ -328,16 +349,16 @@ module.exports = MyForm;
328
349
 
329
350
  The Form class allows for a number of insertion points for extended functionality:
330
351
 
331
- * `configure` Allows for dynamic overwriting of particular points of form configuration based on user session
332
- * `process` Allows for custom formatting and processing of input prior to validation
333
- * `validate` Allows for custom input validation
334
- * `getValues` To define what values the fields are populated with on GET
335
- * `saveValues` To define what is done with successful form submissions
352
+ - `configure` Allows for dynamic overwriting of particular points of form configuration based on user session
353
+ - `process` Allows for custom formatting and processing of input prior to validation
354
+ - `validate` Allows for custom input validation
355
+ - `getValues` To define what values the fields are populated with on GET
356
+ - `saveValues` To define what is done with successful form submissions
336
357
 
337
358
  All of these methods take three arguments of the request, the response and a callback. In all cases the callback should be called with a first argument representing an error.
338
359
 
339
- * `getErrors/setErrors` Define how errors are persisted between the POST and subsequent GET of a form step.
340
- * `locals` Define what additional variables a controller exposes to its template
360
+ - `getErrors/setErrors` Define how errors are persisted between the POST and subsequent GET of a form step.
361
+ - `locals` Define what additional variables a controller exposes to its template
341
362
 
342
363
  These methods are synchronous and take only the request and response obejct as arguments.
343
364
 
@@ -352,6 +373,7 @@ By default the application of a validator is optional on empty strings. If you n
352
373
  Custom validator functions can be passed in field config. These must be named functions and the name is used as the error.type for looking up validation error messages.
353
374
 
354
375
  fields.js
376
+
355
377
  ```js
356
378
  {
357
379
  'field-1': {
@@ -435,9 +457,10 @@ For example, for a dynamic address selection component:
435
457
 
436
458
  ```js
437
459
  MyForm.prototype.configure = function configure(req, res, next) {
438
- req.form.options.fields['address-select'].options = req.sessionModel.get('addresses');
439
- next();
440
- }
460
+ req.form.options.fields["address-select"].options =
461
+ req.sessionModel.get("addresses");
462
+ next();
463
+ };
441
464
  ```
442
465
 
443
466
  ### The FormError class
@@ -445,15 +468,14 @@ MyForm.prototype.configure = function configure(req, res, next) {
445
468
  FormError can be used as a façade to normalise different types of error one may receive / trigger, and to be subsequently returned from a controller.
446
469
  Its constructor takes a series of options. `title` and `message` have both getters and public methods to define default values.
447
470
 
448
-
449
471
  ```js
450
-
451
472
  let error = new ErrorClass(this.missingDoB, {
452
- key: this.missingDob,
453
- type: 'required',
454
- redirect: '/missingData',
455
- title: 'Something went wrong',
456
- message: 'Please supply a valid date of birth'});
473
+ key: this.missingDob,
474
+ type: "required",
475
+ redirect: "/missingData",
476
+ title: "Something went wrong",
477
+ message: "Please supply a valid date of birth",
478
+ });
457
479
  ```
458
480
 
459
481
  ##hof-behaviour-session
@@ -473,6 +495,7 @@ class MyController extends mix(BaseController).with(Session) {
473
495
  ...
474
496
  }
475
497
  ```
498
+
476
499
  `MyController` now extends `hof-form-controller` and has `hof-behaviour-session` functionality mixed in.
477
500
 
478
501
  ##Functionality
@@ -481,14 +504,13 @@ This mixin extends `hof-form-controller` by persisting the form data to the `ses
481
504
 
482
505
  The following form controller methods are used:
483
506
 
484
- * `getValues(req, res, cb)` - calls callback with `null` and a map of all items in the `sessionModel`, extended with `errorValues` - to persist entered values on current step if validation fails
485
- * `saveValues(req, res, cb)` - Called on success. Sets all step fields in `req.form.values` to the sessionModel, unsets `errorValues`.
486
- * `getErrors(req)` - returns all errors for fields on the current step (`req.form.options.fields`), excluding redirects. Set to `req.form.errors` in `hof-form-controller`.
487
- * `setErrors(err, req)` - called on validation error(s). Sets the current step field values as `errorValues` in sessionModel to be used in `getValues`. Sets `errors` to sessionModel - a map of `field-name: error` to be used in `getErrors`.
488
- * `locals(req, res)` - Extends the result of `super.locals` with `baseUrl` (`req.baseUrl`) and `nextPage` (the result of `this.getNextStep(req, res)`).
489
- * `missingPrereqHandler(req, res)` - Error handler called when a `MISSING_PREREQ` error is thrown from the [check-progress](https://github.com/UKHomeOfficeForms/hof-form-wizard/blob/master/lib/middleware/check-progress.js) middleware. This occurs if a step is visited out of sequence. This error handler causes the user to be redirected to the last completed step, or the first step if none have been completed.
490
- * `errorHandler(err, req, res, next)` - checks if `err.code` is `MISSING_PREREQ`, if so calls `missingPrereqHandler`, if not calls `super` to hand over to parent error handler.
491
-
507
+ - `getValues(req, res, cb)` - calls callback with `null` and a map of all items in the `sessionModel`, extended with `errorValues` - to persist entered values on current step if validation fails
508
+ - `saveValues(req, res, cb)` - Called on success. Sets all step fields in `req.form.values` to the sessionModel, unsets `errorValues`.
509
+ - `getErrors(req)` - returns all errors for fields on the current step (`req.form.options.fields`), excluding redirects. Set to `req.form.errors` in `hof-form-controller`.
510
+ - `setErrors(err, req)` - called on validation error(s). Sets the current step field values as `errorValues` in sessionModel to be used in `getValues`. Sets `errors` to sessionModel - a map of `field-name: error` to be used in `getErrors`.
511
+ - `locals(req, res)` - Extends the result of `super.locals` with `baseUrl` (`req.baseUrl`) and `nextPage` (the result of `this.getNextStep(req, res)`).
512
+ - `missingPrereqHandler(req, res)` - Error handler called when a `MISSING_PREREQ` error is thrown from the [check-progress](https://github.com/UKHomeOfficeForms/hof-form-wizard/blob/master/lib/middleware/check-progress.js) middleware. This occurs if a step is visited out of sequence. This error handler causes the user to be redirected to the last completed step, or the first step if none have been completed.
513
+ - `errorHandler(err, req, res, next)` - checks if `err.code` is `MISSING_PREREQ`, if so calls `missingPrereqHandler`, if not calls `super` to hand over to parent error handler.
492
514
 
493
515
  ##behaviour-hooks
494
516
 
@@ -507,6 +529,7 @@ class MyController extends mix(BaseController).with(Hooks) {
507
529
  ...
508
530
  }
509
531
  ```
532
+
510
533
  `MyController` now extends `hof-form-controller` and has `hof-behaviour-hooks` functionality mixed in.
511
534
 
512
535
  ##Functionality
@@ -514,46 +537,52 @@ class MyController extends mix(BaseController).with(Hooks) {
514
537
  The following hooks are currently supported, the methods are GET/POST pipeline methods from `hof-form-controller`:
515
538
 
516
539
  ####GET
517
- * `_getErrors` - `'pre-getErrors', 'post-getErrors'`
518
- * `_getValues` - `'pre-getValues', 'post-getValues'`
519
- * `_locals` - `'pre-locals', 'post-locals'`
520
- * `render` - `'pre-render', 'post-render'`
540
+
541
+ - `_getErrors` - `'pre-getErrors', 'post-getErrors'`
542
+ - `_getValues` - `'pre-getValues', 'post-getValues'`
543
+ - `_locals` - `'pre-locals', 'post-locals'`
544
+ - `render` - `'pre-render', 'post-render'`
521
545
 
522
546
  ####POST
523
- * `_process` - `'pre-process', 'post-process'`
524
- * `_validate` - `'pre-validate', 'post-validate'`
525
- * `saveValues` - `'pre-saveValues', 'post-saveValues'`
526
- * `successHandler` - `'pre-successHandler', 'post-successHandler'`
547
+
548
+ - `_process` - `'pre-process', 'post-process'`
549
+ - `_validate` - `'pre-validate', 'post-validate'`
550
+ - `saveValues` - `'pre-saveValues', 'post-saveValues'`
551
+ - `successHandler` - `'pre-successHandler', 'post-successHandler'`
527
552
 
528
553
  ###In field config
529
554
 
530
555
  fields.js
556
+
531
557
  ```js
532
558
  module.exports = {
533
- 'field-1': {
559
+ "field-1": {
534
560
  hooks: {
535
- 'post-locals': (req, res, next) => {
561
+ "post-locals": (req, res, next) => {
536
562
  Object.assign(res.locals, {
537
- foo: 'bar'
563
+ foo: "bar",
538
564
  });
539
565
  next();
540
566
  },
541
- 'pre-process': (req, res, next) => {
542
- req.body['field-1'] = req.body['field-1'].toUpperCase();
567
+ "pre-process": (req, res, next) => {
568
+ req.body["field-1"] = req.body["field-1"].toUpperCase();
543
569
  next();
544
- }
545
- }
546
- }
547
- }
570
+ },
571
+ },
572
+ },
573
+ };
548
574
  ```
549
575
 
550
576
  # HOF Model
577
+
551
578
  Simple model for interacting with http/rest apis.
552
579
 
553
580
  ## Usage
581
+
554
582
  ```javascript
555
- const Model = require('./model');
583
+ const Model = require("./model");
556
584
  ```
585
+
557
586
  ## Data Storage
558
587
 
559
588
  Models can be used as basic data storage with set/get and change events.
@@ -566,10 +595,10 @@ Save a property to a model. Properties can be passed as a separate key/value arg
566
595
 
567
596
  ```javascript
568
597
  const model = new Model();
569
- model.set('key', 'value');
598
+ model.set("key", "value");
570
599
  model.set({
571
- firstname: 'John',
572
- lastname: 'Smith'
600
+ firstname: "John",
601
+ lastname: "Smith",
573
602
  });
574
603
  ```
575
604
 
@@ -578,7 +607,7 @@ model.set({
578
607
  Retrieve a property from a model:
579
608
 
580
609
  ```javascript
581
- const val = model.get('key');
610
+ const val = model.get("key");
582
611
  // val = 'value'
583
612
  ```
584
613
 
@@ -597,7 +626,7 @@ const json = model.toJSON();
597
626
 
598
627
  ```javascript
599
628
  const model = new Model();
600
- model.on('change', (changedFields) => {
629
+ model.on("change", (changedFields) => {
601
630
  // changedFields contains a map of the key/value pairs which have changed
602
631
  console.log(changedFields);
603
632
  });
@@ -607,10 +636,10 @@ model.on('change', (changedFields) => {
607
636
 
608
637
  ```javascript
609
638
  const model = new Model();
610
- model.on('change:name', (newValue, oldValue) => {
639
+ model.on("change:name", (newValue, oldValue) => {
611
640
  // handler is passed the new value and the old value as arguents
612
641
  });
613
- model.set('name', 'John Smith');
642
+ model.set("name", "John Smith");
614
643
  ```
615
644
 
616
645
  ### Referenced Fields
@@ -619,12 +648,12 @@ A field can be set to a reference to another field by setting it a value of `$re
619
648
 
620
649
  ```javascript
621
650
  const model = new Model();
622
- model.set('home-address', '1 Main Street');
623
- model.set('contact-address', '$ref:home-address');
651
+ model.set("home-address", "1 Main Street");
652
+ model.set("contact-address", "$ref:home-address");
624
653
 
625
- model.get('contact-address'); // => '1 Main Street';
626
- model.set('home-address', '2 Main Street');
627
- model.get('contact-address'); // => '2 Main Street';
654
+ model.get("contact-address"); // => '1 Main Street';
655
+ model.set("home-address", "2 Main Street");
656
+ model.get("contact-address"); // => '2 Main Street';
628
657
 
629
658
  model.toJSON(); // => { home-address: '2 Main Street', 'contact-address': '2 Main Street' }
630
659
  ```
@@ -633,26 +662,26 @@ Change events will be fired on the referenced field if the underlying value chan
633
662
 
634
663
  ```javascript
635
664
  const model = new Model();
636
- model.set('home-address', '1 Main Street');
637
- model.set('contact-address', '$ref:home-address');
638
- model.on('change:contact-address', (value, oldValue) => {
665
+ model.set("home-address", "1 Main Street");
666
+ model.set("contact-address", "$ref:home-address");
667
+ model.on("change:contact-address", (value, oldValue) => {
639
668
  // this is fired when home-address property changes
640
669
  });
641
670
 
642
- model.set('home-address', '2 Main Street');
671
+ model.set("home-address", "2 Main Street");
643
672
  ```
644
673
 
645
674
  A field can be unreferenced by setting its value to any other value.
646
675
 
647
676
  ```javascript
648
677
  const model = new Model();
649
- model.set('home-address', '1 Main Street');
678
+ model.set("home-address", "1 Main Street");
650
679
 
651
680
  // reference the field
652
- model.set('contact-address', '$ref:home-address');
681
+ model.set("contact-address", "$ref:home-address");
653
682
 
654
683
  // unreference the field
655
- model.set('contact-address', '1 Other Road');
684
+ model.set("contact-address", "1 Other Road");
656
685
  ```
657
686
 
658
687
  ## API Client
@@ -669,7 +698,7 @@ There are three methods for API interaction corresponding to GET, POST, and DELE
669
698
 
670
699
  ```javascript
671
700
  const model = new Model();
672
- model.fetch().then(data => {
701
+ model.fetch().then((data) => {
673
702
  console.log(data);
674
703
  });
675
704
  ```
@@ -679,9 +708,9 @@ model.fetch().then(data => {
679
708
  ```javascript
680
709
  const model = new Model();
681
710
  model.set({
682
- property: 'properties are sent as JSON request body by default'
711
+ property: "properties are sent as JSON request body by default",
683
712
  });
684
- model.save().then(data => {
713
+ model.save().then((data) => {
685
714
  console.log(data);
686
715
  });
687
716
  ```
@@ -691,9 +720,9 @@ The method can also be overwritten by passing options
691
720
  ```javascript
692
721
  const model = new Model();
693
722
  model.set({
694
- property: 'this will be sent as a PUT request'
723
+ property: "this will be sent as a PUT request",
695
724
  });
696
- model.save({ method: 'PUT' }).then(data => {
725
+ model.save({ method: "PUT" }).then((data) => {
697
726
  console.log(data);
698
727
  });
699
728
  ```
@@ -702,7 +731,7 @@ model.save({ method: 'PUT' }).then(data => {
702
731
 
703
732
  ```javascript
704
733
  const model = new Model();
705
- model.delete().then(data => {
734
+ model.delete().then((data) => {
706
735
  console.log(data);
707
736
  });
708
737
  ```
@@ -715,14 +744,16 @@ If no `url` method is defined then the model will use the options parameter and
715
744
  const model = new Model();
716
745
 
717
746
  // make a GET request to http://example.com:3000/foo/bar
718
- model.fetch({
719
- protocol: 'http',
720
- hostname: 'example.com',
721
- port: 3000,
722
- path: '/foo/bar'
723
- }).then(data => {
724
- console.log(data);
725
- });
747
+ model
748
+ .fetch({
749
+ protocol: "http",
750
+ hostname: "example.com",
751
+ port: 3000,
752
+ path: "/foo/bar",
753
+ })
754
+ .then((data) => {
755
+ console.log(data);
756
+ });
726
757
  ```
727
758
 
728
759
  ### Events
@@ -730,29 +761,36 @@ model.fetch({
730
761
  API requests will emit events as part of their lifecycle.
731
762
 
732
763
  `sync` is emitted when an API request is sent
764
+
733
765
  ```javascript
734
- model.on('sync', function (settings) { });
766
+ model.on("sync", function (settings) {});
735
767
  ```
736
768
 
737
769
  `success` is emitted when an API request successfully completes
770
+
738
771
  ```javascript
739
- model.on('success', function (data, settings, statusCode, responseTime) { });
772
+ model.on("success", function (data, settings, statusCode, responseTime) {});
740
773
  ```
741
774
 
742
775
  `fail` is emitted when an API request fails
776
+
743
777
  ```javascript
744
- model.on('fail', function (err, data, settings, statusCode, responseTime) { });
778
+ model.on("fail", function (err, data, settings, statusCode, responseTime) {});
745
779
  ```
746
780
 
747
781
  ### HOF Model APIs
782
+
748
783
  - `Html-To-Pdf Converter`: This extends the HOF model to interact with the html-to-pdf converter API https://github.com/UKHomeOffice/html-pdf-converter. The environmental variable `PDF_CONVERTER_URL` needs to be set to its local url when running in the same kube namespace to the service that wants to use it. This is then followed by the default port `10443` and then the URI for which part of the service you want to consume. For example:`https://html-pdf-converter:10443/convert` when the container is named `html-pdf-converter` in your kube deployment file. This has to be set to `https` for communication between services to work on ACP. However, `settings.rejectUnauthorized = false;` is set in the model to circumvent expired certificates due to this. This is preferable to using:
784
+
749
785
  ```
750
786
  name: NODE_TLS_REJECT_UNAUTHORIZED
751
787
  value: "0"
752
788
  ```
789
+
753
790
  which should NOT be used as it sets ignoring TLS at a global level which could present a MITM (Man-In-The-Middle) attack.
754
791
 
755
792
  Usage: Example below, as per the converter docs (link above) it accepts html and responds with Buffered data in pdf format which can then be either written to a file or attached to a Gov Notify message:
793
+
756
794
  ```
757
795
  const PDFModel = require('hof').apis.pdfConverter;
758
796
 
@@ -762,6 +800,7 @@ const pdfData = await pdfModel.save();
762
800
  ```
763
801
 
764
802
  # HOF Middleware
803
+
765
804
  A collection of commonly used HOF middleware, exports `cookies`, `notFound`, and `errors` on `middleware`
766
805
 
767
806
  ## Arranging the middleware in your app
@@ -772,16 +811,20 @@ The Not Found middleware should be placed after all routes and before the Error
772
811
  ## Cookies
773
812
 
774
813
  ### Usage
814
+
775
815
  ```js
776
- app.use(require('hof').middleware.cookies({
777
- 'cookie-name': 'my-application-cookie',
778
- 'param-name': 'my-query-param'
779
- }));
816
+ app.use(
817
+ require("hof").middleware.cookies({
818
+ "cookie-name": "my-application-cookie",
819
+ "param-name": "my-query-param",
820
+ })
821
+ );
780
822
  ```
781
823
 
782
824
  This middleware must be declared before your other routes.
783
825
 
784
826
  ### Options
827
+
785
828
  The `cookie-name` can be the same as your session cookie. (The
786
829
  middleware will not overwrite it.) Defaults to `hof-cookie-check`.
787
830
 
@@ -802,16 +845,22 @@ Kubernetes healthcheck URLs are provided as defaults if no overrides are supplie
802
845
  Expects there to be a view called 404 in your configured `/views` directory
803
846
 
804
847
  ### Usage
848
+
805
849
  ```js
806
- app.use(require('hof').middleware.notFound({
807
- logger: require('/logger'),
808
- translate: require('hof').i18n({path: path_to_translations/__lng__/__ns__.json}).translate
809
- }));
850
+ app.use(
851
+ require("hof").middleware.notFound({
852
+ logger: require("/logger"),
853
+ translate: require("hof").i18n({
854
+ path: path_to_translations / __lng__ / __ns__.json,
855
+ }).translate,
856
+ })
857
+ );
810
858
  ```
811
859
 
812
- This middleware should be declared *after* your other routes but *before* your errorhandler.
860
+ This middleware should be declared _after_ your other routes but _before_ your errorhandler.
813
861
 
814
862
  ### Options
863
+
815
864
  `logger` can be any object with a warn method.
816
865
 
817
866
  `translate` can be the HOF i18n translate function
@@ -819,42 +868,51 @@ This middleware should be declared *after* your other routes but *before* your e
819
868
  ## Errors
820
869
 
821
870
  ### Usage
871
+
822
872
  ```js
823
- app.use(require('hof').middleware.errors({
824
- logger: require('/logger'),
825
- translate: require('hof').i18n({path: path_to_translations/__lng__/__ns__.json}).translate,
826
- debug: true
827
- }));
873
+ app.use(
874
+ require("hof").middleware.errors({
875
+ logger: require("/logger"),
876
+ translate: require("hof").i18n({
877
+ path: path_to_translations / __lng__ / __ns__.json,
878
+ }).translate,
879
+ debug: true,
880
+ })
881
+ );
828
882
  ```
829
883
 
830
- This middleware must be declared *after* your other routes.
884
+ This middleware must be declared _after_ your other routes.
831
885
 
832
886
  ### Options
887
+
833
888
  `logger` can be any object with an error method.
834
889
 
835
890
  `translate` can be the HOF i18n translate function
836
891
 
837
892
  `debug` set to true will present the stack trace in the form and return the err as the content of the template.
838
893
 
839
- __Note__ If `debug === true` translations will not be served, but the error handler default messages
840
- =======
894
+ # **Note** If `debug === true` translations will not be served, but the error handler default messages
895
+
841
896
  ## Deep translate
842
897
 
843
- deepTranslate middleware supports nested conditional translations in order to show different content in different scenarios. The middleware adds a `translate` function to `req` which is used in various points throughout the architecture. This middleware must be applied before any other middleware which rely on the `req.translate` function. Also when initializing the form wizard, or template mixins, if a `translate` function is provided, this will be used rather than the deepTranslate middleware.
898
+ deepTranslate middleware supports nested conditional translations in order to show different content in different scenarios. The middleware adds a `translate` function to `req` which is used in various points throughout the architecture. This middleware must be applied before any other middleware which rely on the `req.translate` function. Also when initializing the form wizard, or template mixins, if a `translate` function is provided, this will be used rather than the deepTranslate middleware.
844
899
 
845
900
  ### Usage
846
901
 
847
902
  ```js
848
- const i18nFuture = require('hof').i18n;
903
+ const i18nFuture = require("hof").i18n;
849
904
  const i18n = i18nFuture({
850
- path: path.resolve(__dirname, './path/to/translations')
851
- })
852
- app.use(require('hof').middleware.deepTranslate({
853
- translate: i18n.translate.bind(i18n)
854
- }));
905
+ path: path.resolve(__dirname, "./path/to/translations"),
906
+ });
907
+ app.use(
908
+ require("hof").middleware.deepTranslate({
909
+ translate: i18n.translate.bind(i18n),
910
+ })
911
+ );
855
912
  ```
856
913
 
857
914
  locales
915
+
858
916
  ```json
859
917
  "fields": {
860
918
  "field-name": {
@@ -876,10 +934,10 @@ locales
876
934
 
877
935
  Using the translation key `fields.field-name.label` will return different values in different situations depending on the values of named fields. In the above example the following are true:
878
936
 
879
- * If both `dependent-field` and `dependent-field-2` have the value `"value-1"`, the label returned will be `"Label 1"`.
880
- * If the value of `dependent-field` is `"value-1"` and the value of `dependent-field-2` is `"value-2"`, the label returned will be `"Label 2"`.
881
- * If the value of `dependent-field` is `"value-2"` the label returned will be `"Label 3"` regardless of the value of `dependent-field-2`
882
- * The default label `"Fallback label"` will be used if value of `dependent-field` is neither of the given options, or it is `undefined`. It will also be used if the value of `dependent-field` is `"value-1"` and the value of `dependent-field-2` is neither of the given options or it is undefined.
937
+ - If both `dependent-field` and `dependent-field-2` have the value `"value-1"`, the label returned will be `"Label 1"`.
938
+ - If the value of `dependent-field` is `"value-1"` and the value of `dependent-field-2` is `"value-2"`, the label returned will be `"Label 2"`.
939
+ - If the value of `dependent-field` is `"value-2"` the label returned will be `"Label 3"` regardless of the value of `dependent-field-2`
940
+ - The default label `"Fallback label"` will be used if value of `dependent-field` is neither of the given options, or it is `undefined`. It will also be used if the value of `dependent-field` is `"value-1"` and the value of `dependent-field-2` is neither of the given options or it is undefined.
883
941
 
884
942
  # HOF Components
885
943
 
@@ -890,14 +948,15 @@ A component for handling the rendering and processing of 3-input date fields use
890
948
  ## Usage
891
949
 
892
950
  In your fields config:
951
+
893
952
  ```js
894
- const dateComponent = require('hof').components.date;
953
+ const dateComponent = require("hof").components.date;
895
954
 
896
955
  module.exports = {
897
- 'date-field': dateComponent('date-field', {
898
- validate: ['required', 'before']
899
- })
900
- }
956
+ "date-field": dateComponent("date-field", {
957
+ validate: ["required", "before"],
958
+ }),
959
+ };
901
960
  ```
902
961
 
903
962
  The above example will create a new date component with the key `'date-field'` and will apply the validators `required` and `before` (before today).
@@ -906,16 +965,17 @@ The above example will create a new date component with the key `'date-field'` a
906
965
 
907
966
  The following optional configuration options are supported:
908
967
 
909
- * `validate {String|Array}` - validators to use on the processed date field
910
- * `template` - an absolute path to an alternate template.
911
- * `dayOptional {Boolean}` - day defaults to `01` if omitted. Defaults to `false`
912
- * `monthOptional {Boolean}` - month defaults to `01` if omitted. If true then also forces `dayOptional` to be true. Defaults to `false`
968
+ - `validate {String|Array}` - validators to use on the processed date field
969
+ - `template` - an absolute path to an alternate template.
970
+ - `dayOptional {Boolean}` - day defaults to `01` if omitted. Defaults to `false`
971
+ - `monthOptional {Boolean}` - month defaults to `01` if omitted. If true then also forces `dayOptional` to be true. Defaults to `false`
913
972
 
914
973
  ## Labels
915
974
 
916
975
  The three intermedate fields have fallback labels of Day, Month and Year, however custom labels can be used by including the translation at the following path:
917
976
 
918
977
  fields.json
978
+
919
979
  ```json
920
980
  {
921
981
  "field-name": {
@@ -951,7 +1011,6 @@ If no sections config is passed, then the mixin will create a section for each s
951
1011
  }
952
1012
  ```
953
1013
 
954
-
955
1014
  Alternatively, sections can be defined manually as follows:
956
1015
 
957
1016
  ```js
@@ -990,9 +1049,9 @@ Fields can be defined as simple strings of the field key, in which case all defa
990
1049
 
991
1050
  Alternatively, a field can be passed as an object with a `field` property defining the field key, and any additional properties as follows:
992
1051
 
993
- * `step` - `String` defines the step which the user is returned to to edit the field value. By default this is the first step in the form's steps configuration which contains the field.
994
- * `parse` - `Function` can parse the value for the field from the session into a value for display.
995
- * `derivation` - `Object` allows for a new derived field based on a combination of other fields in the form. Note that
1052
+ - `step` - `String` defines the step which the user is returned to to edit the field value. By default this is the first step in the form's steps configuration which contains the field.
1053
+ - `parse` - `Function` can parse the value for the field from the session into a value for display.
1054
+ - `derivation` - `Object` allows for a new derived field based on a combination of other fields in the form. Note that
996
1055
  if both `derivation` and `parse` are specified then parse will be applied to the result of derivation. E.G.
997
1056
  ```javascript
998
1057
  derivation: {
@@ -1000,10 +1059,11 @@ Alternatively, a field can be passed as an object with a `field` property defini
1000
1059
  combiner: (values) => values.map(it => Number(it)).reduce((a, b) => a + b, 0)
1001
1060
  }
1002
1061
  ```
1003
- * `useOriginalValue` - `Object` uses original value of radio button or checkbox label rather than trying to find a translation in the `fields.json` file. This could be due to options that are generated by user input that can not be predicted in advance, which are subsequently used to populate a value in the summary page. One good example is using one of many addresses inputted by a user that is additionally a contact address. See example below:
1004
- ![Firearms Use Original Value Summary Page Example](docs/images/firearms_use_original_value_summary.png)
1062
+ - `useOriginalValue` - `Object` uses original value of radio button or checkbox label rather than trying to find a translation in the `fields.json` file. This could be due to options that are generated by user input that can not be predicted in advance, which are subsequently used to populate a value in the summary page. One good example is using one of many addresses inputted by a user that is additionally a contact address. See example below:
1063
+ ![Firearms Use Original Value Summary Page Example](docs/images/firearms_use_original_value_summary.png)
1064
+
1065
+ - `multipleRowsFromAggregate` - `Object` if this object exists on a field, it uses the `labelCategory`, `valueCategory` and `valueTranslation` values to populate the row's label and value name but also iterates over multiple rows that have been aggregated under one field name. There is one good reference of this in Firearms where the following example is used:
1005
1066
 
1006
- * `multipleRowsFromAggregate` - `Object` if this object exists on a field, it uses the `labelCategory`, `valueCategory` and `valueTranslation` values to populate the row's label and value name but also iterates over multiple rows that have been aggregated under one field name. There is one good reference of this in Firearms where the following example is used:
1007
1067
  ```javascript
1008
1068
  {
1009
1069
  field: 'location-addresses',
@@ -1016,6 +1076,7 @@ Alternatively, a field can be passed as an object with a `field` property defini
1016
1076
  }
1017
1077
  }
1018
1078
  ```
1079
+
1019
1080
  The `location-addresses` field is one that the application has setup to aggregate and store all addresses labelled with the `address` field. Each address is a storage location for firearms, and so there is a sub-category which lists what firearms type is listed under each address (i.e. Full-bore, small-bore, muzzle-loading), and these are stored under the `address-category` field. Along with translations to them in the `fields.json` file living under the `location-address-category` translation header. By utilising these three values one can achieve the following output on the summary page.
1020
1081
 
1021
1082
  ![Firearms Summary Page Example](docs/images/firearms_summary_page_example.png)
@@ -1030,18 +1091,19 @@ The content for section headings and field labels will be loaded from translatio
1030
1091
 
1031
1092
  Translations for section headings are looked for in the following order:
1032
1093
 
1033
- * `pages.confirm.sections.${key}.header`
1034
- * `pages.${key}.header`
1094
+ - `pages.confirm.sections.${key}.header`
1095
+ - `pages.${key}.header`
1035
1096
 
1036
1097
  ### Field labels
1037
1098
 
1038
1099
  Translations for field labels are looked for in the following order:
1039
1100
 
1040
- * `pages.confirm.fields.${key}.label`
1041
- * `fields.${key}.label`
1042
- * `fields.${key}.legend`
1101
+ - `pages.confirm.fields.${key}.label`
1102
+ - `fields.${key}.label`
1103
+ - `fields.${key}.legend`
1043
1104
 
1044
1105
  # Emailer Component
1106
+
1045
1107
  HOF behaviour to send emails
1046
1108
 
1047
1109
  ## Usage
@@ -1078,10 +1140,10 @@ steps: {
1078
1140
 
1079
1141
  In addition to the options passed to `hof-emailer`, the following options can be used:
1080
1142
 
1081
- * `recipient` - _Required_ - defines the address to which email will be sent. This can be set either as a key to retrieve an email address from the session, or explicitly to an email address.
1082
- * `template` - _Required_ - defines the mustache template used to render the email content.
1083
- * `subject` - defines the subject line of the email.
1084
- * `parse` - parses the session model into an object used to populate the template.
1143
+ - `recipient` - _Required_ - defines the address to which email will be sent. This can be set either as a key to retrieve an email address from the session, or explicitly to an email address.
1144
+ - `template` - _Required_ - defines the mustache template used to render the email content.
1145
+ - `subject` - defines the subject line of the email.
1146
+ - `parse` - parses the session model into an object used to populate the template.
1085
1147
 
1086
1148
  `recipient` and `subject` options can also be defined as functions, which will be passed a copy of the session model and a translation function as arguments, and should return a string value.
1087
1149
 
@@ -1089,7 +1151,7 @@ In addition to the options passed to `hof-emailer`, the following options can be
1089
1151
  // use a translated value for the email subject line
1090
1152
  const emailer = EmailBehaviour({
1091
1153
  // ...
1092
- subject: (model, translate) => translate('email.success.subject')
1154
+ subject: (model, translate) => translate("email.success.subject"),
1093
1155
  });
1094
1156
  ```
1095
1157
 
@@ -1107,24 +1169,23 @@ $ npm install hof-emailer --save
1107
1169
 
1108
1170
  ```js
1109
1171
  // first create an emailer instance
1110
- const Emailer = require('hof').components.email.emailer;
1172
+ const Emailer = require("hof").components.email.emailer;
1111
1173
  const emailer = new Emailer({
1112
- from: 'sender@example.com',
1113
- transport: 'smtp',
1174
+ from: "sender@example.com",
1175
+ transport: "smtp",
1114
1176
  transportOptions: {
1115
- host: 'my.smtp.host',
1116
- port: 25
1117
- }
1177
+ host: "my.smtp.host",
1178
+ port: 25,
1179
+ },
1118
1180
  });
1119
1181
 
1120
1182
  // then you can use your emailer to send emails
1121
- const to = 'recipient@example.com';
1122
- const body = 'This is the email body';
1123
- const subject = 'Important email!'
1124
- emailer.send(to, body, subject)
1125
- .then(() => {
1126
- console.log(`Email sent to ${to}!`);
1127
- });
1183
+ const to = "recipient@example.com";
1184
+ const body = "This is the email body";
1185
+ const subject = "Important email!";
1186
+ emailer.send(to, body, subject).then(() => {
1187
+ console.log(`Email sent to ${to}!`);
1188
+ });
1128
1189
  ```
1129
1190
 
1130
1191
  ## Options
@@ -1152,6 +1213,7 @@ The following transport options are available:
1152
1213
  - `auth.pass` <String>: Mailserver authorisation password.
1153
1214
 
1154
1215
  ### `ses`
1216
+
1155
1217
  [nodemailer-ses-transport](https://github.com/andris9/nodemailer-ses-transport)
1156
1218
 
1157
1219
  #### Options
@@ -1184,6 +1246,7 @@ transportOptions: {
1184
1246
  open: true
1185
1247
  }
1186
1248
  ```
1249
+
1187
1250
  ### `stub`
1188
1251
 
1189
1252
  Disables sending email. No options are required.
@@ -1191,6 +1254,7 @@ Disables sending email. No options are required.
1191
1254
  # UTILITIES
1192
1255
 
1193
1256
  # Autofill Utility
1257
+
1194
1258
  A webdriverio plugin to automate filling a form
1195
1259
 
1196
1260
  ## Usage
@@ -1198,10 +1262,10 @@ A webdriverio plugin to automate filling a form
1198
1262
  First, add the command to your webdriverio client:
1199
1263
 
1200
1264
  ```js
1201
- const webdriver = require('webdriverio');
1265
+ const webdriver = require("webdriverio");
1202
1266
  const client = webdriver.remote(options);
1203
1267
 
1204
- client.addCommand('goto', require('hof-util-autofill')(client));
1268
+ client.addCommand("goto", require("hof-util-autofill")(client));
1205
1269
  ```
1206
1270
 
1207
1271
  The command can be given any name you like, here we've called it `goto`.
@@ -1209,32 +1273,36 @@ The command can be given any name you like, here we've called it `goto`.
1209
1273
  Then you can use the command as normal as part of your webdriver command chain.
1210
1274
 
1211
1275
  ```js
1212
- it('completes a form to a certain step automatically', () => {
1213
- return browser.goto('/confirm')
1276
+ it("completes a form to a certain step automatically", () => {
1277
+ return browser
1278
+ .goto("/confirm")
1214
1279
  .getUrl()
1215
1280
  .then((url) => {
1216
- assert.ok(url.indexOf('/confirm') > -1);
1281
+ assert.ok(url.indexOf("/confirm") > -1);
1217
1282
  });
1218
1283
  });
1219
1284
 
1220
- it('uses any data passed as a second argument to fill out the form', () => {
1221
- const inputs = { 'first-name': 'David', 'last-name': 'Hasselhoff' };
1222
- return browser.goto('/confirm', inputs)
1223
- .$('span.full-name')
1285
+ it("uses any data passed as a second argument to fill out the form", () => {
1286
+ const inputs = { "first-name": "David", "last-name": "Hasselhoff" };
1287
+ return browser
1288
+ .goto("/confirm", inputs)
1289
+ .$("span.full-name")
1224
1290
  .getText()
1225
- .then(name => {
1226
- assert.equal(name, 'David HasselHoff');
1291
+ .then((name) => {
1292
+ assert.equal(name, "David HasselHoff");
1227
1293
  });
1228
1294
  });
1229
1295
 
1230
- it('saves screenshots of errors to specified screenshot location', () => {
1296
+ it("saves screenshots of errors to specified screenshot location", () => {
1231
1297
  const inputs = {};
1232
- return browser.goto('/confirm', inputs, { screenshots: '/path/to/output/dir' });
1298
+ return browser.goto("/confirm", inputs, {
1299
+ screenshots: "/path/to/output/dir",
1300
+ });
1233
1301
  });
1234
1302
 
1235
- it('tries a pre-specified number of times to get past stuck loops', () => {
1303
+ it("tries a pre-specified number of times to get past stuck loops", () => {
1236
1304
  const inputs = {};
1237
- return browser.goto('/confirm', inputs, { maxLoops: 1 });
1305
+ return browser.goto("/confirm", inputs, { maxLoops: 1 });
1238
1306
  });
1239
1307
  ```
1240
1308
 
@@ -1242,10 +1310,11 @@ it('tries a pre-specified number of times to get past stuck loops', () => {
1242
1310
 
1243
1311
  Options are passed as a third argument to the exposed method. The following options are available:
1244
1312
 
1245
- * `maxLoops` - determines how many times a step will retry if it resolves back to itself on submission before failing. Default: `3`
1246
- * `screenshots` - specifies a location to save screenshots of the page when it gets stuck. If not specified then no screenshots are saved.
1313
+ - `maxLoops` - determines how many times a step will retry if it resolves back to itself on submission before failing. Default: `3`
1314
+ - `screenshots` - specifies a location to save screenshots of the page when it gets stuck. If not specified then no screenshots are saved.
1247
1315
 
1248
1316
  # Test-Data Utility
1317
+
1249
1318
  Generator for test fixtures
1250
1319
 
1251
1320
  ## Usage
@@ -1255,7 +1324,7 @@ The library contains a number of generators for values of certain types. Values
1255
1324
  ### Example:
1256
1325
 
1257
1326
  ```js
1258
- const TestData = require('hof').utils.testData;
1327
+ const TestData = require("hof").utils.testData;
1259
1328
 
1260
1329
  console.log(TestData.name);
1261
1330
  // "David Fletcher"
@@ -1266,22 +1335,22 @@ console.log(TestData.name);
1266
1335
 
1267
1336
  ## Available generators
1268
1337
 
1269
- * `firstname`
1270
- * `lastname`
1271
- * `name`
1272
- * `email`
1273
- * `phone`
1274
- * `streetname`
1275
- * `streetsuffix`
1276
- * `address` - `${number(1,100)} ${streetname} ${streetsuffix}`
1277
- * `postcode`
1278
- * `country` - a random country from [homeoffice-countries](npmjs.com/homeoffice-countries)
1338
+ - `firstname`
1339
+ - `lastname`
1340
+ - `name`
1341
+ - `email`
1342
+ - `phone`
1343
+ - `streetname`
1344
+ - `streetsuffix`
1345
+ - `address` - `${number(1,100)} ${streetname} ${streetsuffix}`
1346
+ - `postcode`
1347
+ - `country` - a random country from [homeoffice-countries](npmjs.com/homeoffice-countries)
1279
1348
 
1280
1349
  ## Functions
1281
1350
 
1282
- * `number(min, max)` - returns an integer between `min` and `max`
1283
- * `number(max)` - returns an integer between 0 and `max`
1284
- * `number()` - returns an integer between 0 and 100
1351
+ - `number(min, max)` - returns an integer between `min` and `max`
1352
+ - `number(max)` - returns an integer between 0 and `max`
1353
+ - `number()` - returns an integer between 0 and 100
1285
1354
 
1286
1355
  # Countries Utility
1287
1356
 
@@ -1307,23 +1376,24 @@ In field configuration:
1307
1376
 
1308
1377
  If needed, the following options can be passed into the countries function:
1309
1378
 
1310
- * `filter` - `Function` - applies a filter to the list of country names before mapping them
1311
- * `parse` - `Function` - applies a transform to the country name before setting the label
1379
+ - `filter` - `Function` - applies a filter to the list of country names before mapping them
1380
+ - `parse` - `Function` - applies a transform to the country name before setting the label
1312
1381
 
1313
1382
  ## i18n
1314
1383
 
1315
1384
  If you wish to translate the countries into outher languages, you may want the labels to be in the form of translation keys. In this case you can use a `parse` option to convert the country names into a translation key:
1316
1385
 
1317
1386
  ```js
1318
- const countries = require('hof').utils.countries;
1387
+ const countries = require("hof").utils.countries;
1319
1388
  const options = countries({
1320
- parse: country => `countries.${country.toLowerCase().split(' ').join('-')}`
1389
+ parse: (country) => `countries.${country.toLowerCase().split(" ").join("-")}`,
1321
1390
  });
1322
1391
  ```
1323
1392
 
1324
1393
  You can then define a single translation for country names to be used for all country list instances.
1325
1394
 
1326
1395
  # FRONTEND
1396
+
1327
1397
  ## Template Mixins
1328
1398
 
1329
1399
  A middleware that exposes a series of Mustache mixins on `res.locals` to ease usage of forms, translations, and some other things.
@@ -1337,20 +1407,20 @@ npm install [--save] hof-template-mixins;
1337
1407
  ## Usage
1338
1408
 
1339
1409
  ```javascript
1340
- var express = require('express');
1410
+ var express = require("express");
1341
1411
 
1342
- var i18n = require('i18n-future');
1343
- var mixins = require('hof').frontend.mixins;
1412
+ var i18n = require("i18n-future");
1413
+ var mixins = require("hof").frontend.mixins;
1344
1414
 
1345
- app.set('view engine', 'html');
1346
- app.set('views', path.join(__dirname, '/views'));
1415
+ app.set("view engine", "html");
1416
+ app.set("views", path.join(__dirname, "/views"));
1347
1417
 
1348
1418
  app.use(i18n.middleware());
1349
1419
  app.use(mixins());
1350
1420
 
1351
1421
  app.use(function (req, res) {
1352
- // NOTE: res.locals.partials has been set.
1353
- res.render('example-template');
1422
+ // NOTE: res.locals.partials has been set.
1423
+ res.render("example-template");
1354
1424
  });
1355
1425
  ```
1356
1426
 
@@ -1414,6 +1484,7 @@ renderField
1414
1484
  ```
1415
1485
 
1416
1486
  ### qs
1487
+
1417
1488
  This mixin takes a `key=value` query string and returns a query string with the extra params appended. If the key is already present in the query string, the value passed to the mixin is used
1418
1489
 
1419
1490
  ```html
@@ -1425,34 +1496,29 @@ This mixin takes a `key=value` query string and returns a query string with the
1425
1496
  The renderField mixin can be called in your template to render all fields. This will lookup the field.mixin in res.locals and call it passing the field key.
1426
1497
 
1427
1498
  ```html
1428
- {{#fields}}
1429
- {{#renderField}}{{/renderField}}
1430
- {{/fields}}
1499
+ {{#fields}} {{#renderField}}{{/renderField}} {{/fields}}
1431
1500
  ```
1432
1501
 
1433
1502
  fields.js
1503
+
1434
1504
  ```js
1435
1505
  module.exports = {
1436
- 'my-field': {
1437
- mixin: 'input-text'
1438
- }
1439
- }
1506
+ "my-field": {
1507
+ mixin: "input-text",
1508
+ },
1509
+ };
1440
1510
  ```
1441
1511
 
1442
1512
  If mixin is omitted `input-text` will be used
1443
1513
 
1444
1514
  To disable auto-rendering of a field, set `disableRender: true` in the field config. This is required when using the `child` element rendering functionality to prevent the field being rendered multiple times.
1445
1515
 
1446
-
1447
- ### Render a single field ###
1516
+ ### Render a single field
1448
1517
 
1449
1518
  To render a specific fields in your templates use the mixin name (matching those above) and field name like so...
1450
1519
 
1451
1520
  ```html
1452
- {{#input-text}}myTextField{{/input-text}}
1453
-
1454
- {{#select}}mySelectMenu{{/select}}
1455
-
1521
+ {{#input-text}}myTextField{{/input-text}} {{#select}}mySelectMenu{{/select}}
1456
1522
  {{#radio-group}}myRadioGroup{{/radio-group}}
1457
1523
  ```
1458
1524
 
@@ -1471,13 +1537,12 @@ To render a specific fields in your templates use the mixin name (matching those
1471
1537
  - `toggle`: Can be used to toggle the display of the HTML element with a matching `id`. See [hof-frontend-toolkit](https://github.com/UKHomeOfficeForms/hof-frontend-toolkit/blob/master/assets/javascript/progressive-reveal.js) for details.
1472
1538
  - `attributes`: A hash of key/value pairs applicable to a HTML `textarea` field. Each key/value is assigned as an attribute of the `textarea`. For example `spellcheck="true"`.
1473
1539
  - `child`: Render a child partial beneath each option in an `optionGroup`. Accepts a custom mustache template string, a custom partial in the format `partials/{your-partial-name}`, `'html'` which is used to specify the html for the field has already been prerendered, such as in [hof-component-date](https://github.com/UKHomeOfficeForms/hof-component-date) or a template mixin key which will be rendered within a panel element partial.
1474
- - `isPageHeading`: Applicable to `checkbox` and `radio` controls. Sets the legend as the page heading on single page questions.
1540
+ - `isPageHeading`: Applicable to `checkbox` and `radio`, `text input` and `textarea` controls. Sets the legend as the page heading on single page questions.
1475
1541
  - `isWarning`: Applicable to `checkbox` and `radio` controls. Allows warning text to be placed after page headings on single page questions if required.
1476
1542
 
1477
-
1478
1543
  # HOF-template-partials
1479
1544
 
1480
- Home Office Forms template partials is a collection of mustache partials commonly used in HOF applications. It also contains a collection of i18n translations used within the template partials. All contents are designed to be extended in your individual applications.
1545
+ Home Office Forms template partials is a collection of mustache partials commonly used in HOF applications. It also contains a collection of i18n translations used within the template partials. All contents are designed to be extended in your individual applications.
1481
1546
 
1482
1547
  ## Usage
1483
1548
 
@@ -1488,14 +1553,14 @@ Home Office Forms template partials is a collection of mustache partials commonl
1488
1553
  Template partials can be used by adding the route to the views directory to your express application views setting. You will need to be using the HTML view engine with Hogan and Mustache.
1489
1554
 
1490
1555
  ```js
1491
- var app = require('express')();
1556
+ var app = require("express")();
1492
1557
 
1493
- app.set('view engine', 'html');
1494
- app.set('views', [
1558
+ app.set("view engine", "html");
1559
+ app.set("views", [
1495
1560
  // your application shared views
1496
- path.resolve(__dirname, './path/to/views'),
1561
+ path.resolve(__dirname, "./path/to/views"),
1497
1562
  // the module exports paths to views and translations directories
1498
- require('hof').frontend.partials.views
1563
+ require("hof").frontend.partials.views,
1499
1564
  ]);
1500
1565
  ```
1501
1566
 
@@ -1506,14 +1571,14 @@ The views are now available when calling `res.render('view-name')` from express.
1506
1571
  When used in a hof application in conjunction with [express-partial-templates](https://github.com/UKHomeOffice/express-partial-templates) the contents of the views directory are added to `res.locals.partials`. These are added right to left so conflicting views are resolved from the left-most directory.
1507
1572
 
1508
1573
  ```js
1509
- var app = require('express')();
1574
+ var app = require("express")();
1510
1575
 
1511
- app.set('view engine', 'html');
1512
- app.set('views', [
1513
- path.resolve(__dirname, './path/to/views'),
1514
- require('hof').frontend.partials.views
1576
+ app.set("view engine", "html");
1577
+ app.set("views", [
1578
+ path.resolve(__dirname, "./path/to/views"),
1579
+ require("hof").frontend.partials.views,
1515
1580
  ]);
1516
- app.use(require('express-partial-templates')(app));
1581
+ app.use(require("express-partial-templates")(app));
1517
1582
 
1518
1583
  app.use(function (req, res, next) {
1519
1584
  // res.locals.partials contains all views from the views dir in this repo
@@ -1529,8 +1594,8 @@ The provided translations are designed to be used in conjunction with a translat
1529
1594
  The exported `resources` method will return a compiled object containing the translations, which can be passed to an `i18n` instance as a pre-compiled resource.
1530
1595
 
1531
1596
  ```js
1532
- const translate = require('i18n-future').middleware({
1533
- resources: require('hof').frontend.partials.resources()
1597
+ const translate = require("i18n-future").middleware({
1598
+ resources: require("hof").frontend.partials.resources(),
1534
1599
  });
1535
1600
  app.use(translate);
1536
1601
  ```
@@ -1538,19 +1603,19 @@ app.use(translate);
1538
1603
  By default the namespace for this translation is `default`. A custom namespace can be specified by passing it as an argument to the `resources` function.
1539
1604
 
1540
1605
  ```js
1541
- const translate = require('i18n-future').middleware({
1542
- resources: require('hof').frontend.partials.resources('hof-common'),
1543
- fallbackNamespace: 'hof-common'
1606
+ const translate = require("i18n-future").middleware({
1607
+ resources: require("hof").frontend.partials.resources("hof-common"),
1608
+ fallbackNamespace: "hof-common",
1544
1609
  });
1545
1610
  app.use(translate);
1546
1611
  ```
1612
+
1547
1613
  ### Cookie Banner
1548
1614
 
1549
1615
  The cookie banner has a placeholder named serviceName that you can set within the locals of your hof application so that the appropriate value is displayed.
1550
1616
 
1551
1617
  Set `appName` if your hof settings being passed to hof to take advantage of this.
1552
1618
 
1553
-
1554
1619
  # HOF FRONTEND THEME
1555
1620
 
1556
1621
  ## Usage
@@ -1602,11 +1667,13 @@ When used as part of an express app, a middleware is returned which will add a s
1602
1667
  It will also add the template as a mustache partial with a name of "govuk-template".
1603
1668
 
1604
1669
  ### To configure express middleware
1670
+
1605
1671
  ```
1606
1672
  app.use(require('hof').frontend.govUKTemplate([options]);
1607
1673
  ```
1608
1674
 
1609
1675
  ### To use the mustache partial
1676
+
1610
1677
  ```
1611
1678
  {{< govuk-template}}
1612
1679
  {{$pageTitle}}An example page{{/pageTitle}}
@@ -1620,11 +1687,12 @@ app.use(require('hof').frontend.govUKTemplate([options]);
1620
1687
 
1621
1688
  A number of options can be passed with the app into the setup method:
1622
1689
 
1623
- * `path` - Sets the base path for the location of static assets - Default: `/govuk-assets`
1690
+ - `path` - Sets the base path for the location of static assets - Default: `/govuk-assets`
1624
1691
 
1625
1692
  Other options are passed onto the [serve-static](https://www.npmjs.com/package/serve-static) configuration, and more details can be found in [the serve-static documentation](https://www.npmjs.com/package/serve-static)
1626
1693
 
1627
1694
  # Nonce values
1695
+
1628
1696
  Version 18.0.0 and above of HOF provides and requires a nonce value for all inline javascript, as unsafe-inline is disabled.
1629
1697
  Older versions (pre 18.0.0) will work with the hof-govuk-template templates as expected as the nonce value fields will only be added
1630
1698
  if a nonce value is provided by the version of HOF.
@@ -1638,16 +1706,19 @@ There is an example implementation in [demo application](https://github.com/UKHo
1638
1706
  There is a sandbox application for developers to test components directly in hof called [sandbox](/sandbox)
1639
1707
 
1640
1708
  # HOF FRONTEND TOOLKIT
1709
+
1641
1710
  Set of common UI patterns/styles for HOF projects
1642
1711
 
1643
1712
  ## Images
1713
+
1644
1714
  Copy `assets/images/hmpo` to your image directory. Images are loaded by using the `file-url` function provided by [GOV.UK frontend toolkit](https://github.com/alphagov/govuk_frontend_toolkit). The `file-url` function uses the `$path` variable which is set before the toolkit's modules are loaded.
1645
1715
 
1646
1716
  ## Vendor JavaScript
1717
+
1647
1718
  Additional vendor JavaScript files are included. These are:
1648
1719
 
1649
- * details.polyfill.js
1650
- * indexof.polyfill.js
1651
- * safari-cachebuster.js
1720
+ - details.polyfill.js
1721
+ - indexof.polyfill.js
1722
+ - safari-cachebuster.js
1652
1723
 
1653
1724
  Copy `assets/javascript/vendor` into your javascript directory (ie `hmpo/vendor`) and compile them with your JavaScript.