@defra/forms-engine-plugin 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/.server/server/index.js +0 -4
  2. package/.server/server/index.js.map +1 -1
  3. package/.server/server/plugins/engine/helpers.js +3 -0
  4. package/.server/server/plugins/engine/helpers.js.map +1 -1
  5. package/.server/server/plugins/engine/index.js +27 -1
  6. package/.server/server/plugins/engine/index.js.map +1 -1
  7. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js +2 -4
  8. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -1
  9. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +4 -10
  10. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
  11. package/.server/server/plugins/engine/pageControllers/StatusPageController.js +2 -3
  12. package/.server/server/plugins/engine/pageControllers/StatusPageController.js.map +1 -1
  13. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +2 -4
  14. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
  15. package/.server/server/plugins/engine/plugin.js +65 -6
  16. package/.server/server/plugins/engine/plugin.js.map +1 -1
  17. package/.server/server/plugins/engine/types.js.map +1 -1
  18. package/.server/server/{views → plugins/engine/views}/components/service-banner/template.test.js +1 -1
  19. package/.server/server/plugins/engine/views/components/service-banner/template.test.js.map +1 -0
  20. package/.server/server/{views → plugins/engine/views}/components/tag-env/template.test.js +1 -1
  21. package/.server/server/plugins/engine/views/components/tag-env/template.test.js.map +1 -0
  22. package/.server/server/services/cacheService.js +5 -2
  23. package/.server/server/services/cacheService.js.map +1 -1
  24. package/.server/typings/hapi/index.d.js.map +1 -1
  25. package/README.md +215 -4
  26. package/package.json +3 -3
  27. package/src/client/javascripts/application.js +87 -0
  28. package/src/client/javascripts/file-upload.js +386 -0
  29. package/src/client/stylesheets/_code.scss +33 -0
  30. package/src/client/stylesheets/_govuk-frontend.scss +4 -0
  31. package/src/client/stylesheets/_prose.scss +56 -0
  32. package/src/client/stylesheets/_service-banner.scss +24 -0
  33. package/src/client/stylesheets/_summary-list.scss +28 -0
  34. package/src/client/stylesheets/_tag-env.scss +24 -0
  35. package/src/client/stylesheets/application.scss +14 -0
  36. package/src/common/cookies.js +58 -0
  37. package/src/common/cookies.test.js +23 -0
  38. package/src/common/types.js +5 -0
  39. package/src/config/index.ts +271 -0
  40. package/src/index.ts +31 -0
  41. package/src/server/common/helpers/logging/logger-options.test.ts +50 -0
  42. package/src/server/common/helpers/logging/logger-options.ts +46 -0
  43. package/src/server/common/helpers/logging/logger.ts +7 -0
  44. package/src/server/common/helpers/logging/request-logger.ts +9 -0
  45. package/src/server/common/helpers/logging/request-tracing.js +10 -0
  46. package/src/server/common/helpers/redis-client.js +70 -0
  47. package/src/server/constants.js +1 -0
  48. package/src/server/forms/README.md +10 -0
  49. package/src/server/forms/components.json +1015 -0
  50. package/src/server/forms/report-a-terrorist.json +270 -0
  51. package/src/server/forms/runner-components-test.json +365 -0
  52. package/src/server/forms/test.json +581 -0
  53. package/src/server/index.test.ts +582 -0
  54. package/src/server/index.ts +135 -0
  55. package/src/server/plugins/blankie.test.ts +73 -0
  56. package/src/server/plugins/blankie.ts +48 -0
  57. package/src/server/plugins/crumb.ts +20 -0
  58. package/src/server/plugins/engine/README.md +87 -0
  59. package/src/server/plugins/engine/components/AutocompleteField.test.ts +294 -0
  60. package/src/server/plugins/engine/components/AutocompleteField.ts +49 -0
  61. package/src/server/plugins/engine/components/CheckboxesField.test.ts +379 -0
  62. package/src/server/plugins/engine/components/CheckboxesField.ts +106 -0
  63. package/src/server/plugins/engine/components/ComponentBase.ts +97 -0
  64. package/src/server/plugins/engine/components/ComponentCollection.ts +278 -0
  65. package/src/server/plugins/engine/components/DatePartsField.test.ts +822 -0
  66. package/src/server/plugins/engine/components/DatePartsField.ts +264 -0
  67. package/src/server/plugins/engine/components/Details.test.ts +49 -0
  68. package/src/server/plugins/engine/components/Details.ts +30 -0
  69. package/src/server/plugins/engine/components/EmailAddressField.test.ts +395 -0
  70. package/src/server/plugins/engine/components/EmailAddressField.ts +55 -0
  71. package/src/server/plugins/engine/components/FileUploadField.test.ts +778 -0
  72. package/src/server/plugins/engine/components/FileUploadField.ts +262 -0
  73. package/src/server/plugins/engine/components/FormComponent.ts +249 -0
  74. package/src/server/plugins/engine/components/Html.test.ts +48 -0
  75. package/src/server/plugins/engine/components/Html.ts +29 -0
  76. package/src/server/plugins/engine/components/InsetText.test.ts +48 -0
  77. package/src/server/plugins/engine/components/InsetText.ts +27 -0
  78. package/src/server/plugins/engine/components/List.test.ts +76 -0
  79. package/src/server/plugins/engine/components/List.ts +72 -0
  80. package/src/server/plugins/engine/components/ListFormComponent.ts +140 -0
  81. package/src/server/plugins/engine/components/MonthYearField.test.ts +567 -0
  82. package/src/server/plugins/engine/components/MonthYearField.ts +222 -0
  83. package/src/server/plugins/engine/components/MultilineTextField.test.ts +558 -0
  84. package/src/server/plugins/engine/components/MultilineTextField.ts +138 -0
  85. package/src/server/plugins/engine/components/NumberField.test.ts +701 -0
  86. package/src/server/plugins/engine/components/NumberField.ts +163 -0
  87. package/src/server/plugins/engine/components/RadiosField.test.ts +288 -0
  88. package/src/server/plugins/engine/components/RadiosField.ts +24 -0
  89. package/src/server/plugins/engine/components/SelectField.test.ts +288 -0
  90. package/src/server/plugins/engine/components/SelectField.ts +47 -0
  91. package/src/server/plugins/engine/components/SelectionControlField.ts +43 -0
  92. package/src/server/plugins/engine/components/TelephoneNumberField.test.ts +356 -0
  93. package/src/server/plugins/engine/components/TelephoneNumberField.ts +67 -0
  94. package/src/server/plugins/engine/components/TextField.test.ts +489 -0
  95. package/src/server/plugins/engine/components/TextField.ts +96 -0
  96. package/src/server/plugins/engine/components/UkAddressField.test.ts +623 -0
  97. package/src/server/plugins/engine/components/UkAddressField.ts +172 -0
  98. package/src/server/plugins/engine/components/YesNoField.test.ts +248 -0
  99. package/src/server/plugins/engine/components/YesNoField.ts +31 -0
  100. package/src/server/plugins/engine/components/constants.ts +1 -0
  101. package/src/server/plugins/engine/components/helpers.ts +330 -0
  102. package/src/server/plugins/engine/components/index.ts +24 -0
  103. package/src/server/plugins/engine/components/types.ts +117 -0
  104. package/src/server/plugins/engine/configureEnginePlugin.ts +47 -0
  105. package/src/server/plugins/engine/helpers.test.ts +791 -0
  106. package/src/server/plugins/engine/helpers.ts +384 -0
  107. package/src/server/plugins/engine/index.ts +47 -0
  108. package/src/server/plugins/engine/models/FormModel.test.ts +42 -0
  109. package/src/server/plugins/engine/models/FormModel.ts +443 -0
  110. package/src/server/plugins/engine/models/RepeatingSummaryViewModel.ts +0 -0
  111. package/src/server/plugins/engine/models/Section.ts +0 -0
  112. package/src/server/plugins/engine/models/SummaryViewModel.test.ts +209 -0
  113. package/src/server/plugins/engine/models/SummaryViewModel.ts +220 -0
  114. package/src/server/plugins/engine/models/index.ts +2 -0
  115. package/src/server/plugins/engine/models/types.ts +114 -0
  116. package/src/server/plugins/engine/outputFormatters/human/v1.test.ts +143 -0
  117. package/src/server/plugins/engine/outputFormatters/human/v1.ts +73 -0
  118. package/src/server/plugins/engine/outputFormatters/index.test.ts +17 -0
  119. package/src/server/plugins/engine/outputFormatters/index.ts +44 -0
  120. package/src/server/plugins/engine/outputFormatters/machine/v1.test.ts +229 -0
  121. package/src/server/plugins/engine/outputFormatters/machine/v1.ts +140 -0
  122. package/src/server/plugins/engine/outputFormatters/machine/v2.test.ts +229 -0
  123. package/src/server/plugins/engine/outputFormatters/machine/v2.ts +153 -0
  124. package/src/server/plugins/engine/pageControllers/FileUploadPageController.test.ts +1116 -0
  125. package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +447 -0
  126. package/src/server/plugins/engine/pageControllers/PageController.test.ts +205 -0
  127. package/src/server/plugins/engine/pageControllers/PageController.ts +176 -0
  128. package/src/server/plugins/engine/pageControllers/QuestionPageController.test.ts +1264 -0
  129. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +565 -0
  130. package/src/server/plugins/engine/pageControllers/README.md +28 -0
  131. package/src/server/plugins/engine/pageControllers/RepeatPageController.test.ts +264 -0
  132. package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +458 -0
  133. package/src/server/plugins/engine/pageControllers/StartPageController.ts +18 -0
  134. package/src/server/plugins/engine/pageControllers/StatusPageController.ts +51 -0
  135. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +262 -0
  136. package/src/server/plugins/engine/pageControllers/TerminalController.test.ts +28 -0
  137. package/src/server/plugins/engine/pageControllers/TerminalPageController.ts +19 -0
  138. package/src/server/plugins/engine/pageControllers/helpers.test.ts +198 -0
  139. package/src/server/plugins/engine/pageControllers/helpers.ts +101 -0
  140. package/src/server/plugins/engine/pageControllers/index.ts +10 -0
  141. package/src/server/plugins/engine/pageControllers/validationOptions.ts +89 -0
  142. package/src/server/plugins/engine/plugin.ts +753 -0
  143. package/src/server/plugins/engine/services/formSubmissionService.js +46 -0
  144. package/src/server/plugins/engine/services/formsService.js +46 -0
  145. package/src/server/plugins/engine/services/formsService.test.js +90 -0
  146. package/src/server/plugins/engine/services/index.js +3 -0
  147. package/src/server/plugins/engine/services/notifyService.test.ts +132 -0
  148. package/src/server/plugins/engine/services/notifyService.ts +64 -0
  149. package/src/server/plugins/engine/services/uploadService.js +60 -0
  150. package/src/server/plugins/engine/types.ts +317 -0
  151. package/src/server/plugins/engine/views/components/autocompletefield.html +5 -0
  152. package/src/server/plugins/engine/views/components/checkboxesfield.html +5 -0
  153. package/src/server/plugins/engine/views/components/datepartsfield.html +5 -0
  154. package/src/server/plugins/engine/views/components/debug/macro.njk +3 -0
  155. package/src/server/plugins/engine/views/components/debug/template.njk +13 -0
  156. package/src/server/plugins/engine/views/components/details.html +6 -0
  157. package/src/server/plugins/engine/views/components/emailaddressfield.html +5 -0
  158. package/src/server/plugins/engine/views/components/fileuploadfield-key.html +8 -0
  159. package/src/server/plugins/engine/views/components/fileuploadfield-value.html +3 -0
  160. package/src/server/plugins/engine/views/components/fileuploadfield.html +24 -0
  161. package/src/server/plugins/engine/views/components/html.html +3 -0
  162. package/src/server/plugins/engine/views/components/insettext.html +7 -0
  163. package/src/server/plugins/engine/views/components/list.html +36 -0
  164. package/src/server/plugins/engine/views/components/monthyearfield.html +5 -0
  165. package/src/server/plugins/engine/views/components/multilinetextfield.html +10 -0
  166. package/src/server/plugins/engine/views/components/numberfield.html +5 -0
  167. package/src/server/plugins/engine/views/components/radiosfield.html +5 -0
  168. package/src/server/plugins/engine/views/components/selectfield.html +5 -0
  169. package/src/server/plugins/engine/views/components/service-banner/macro.njk +3 -0
  170. package/src/server/plugins/engine/views/components/service-banner/template.njk +20 -0
  171. package/src/server/plugins/engine/views/components/service-banner/template.test.js +43 -0
  172. package/src/server/plugins/engine/views/components/tag-env/macro.njk +3 -0
  173. package/src/server/plugins/engine/views/components/tag-env/template.njk +30 -0
  174. package/src/server/plugins/engine/views/components/tag-env/template.test.js +66 -0
  175. package/src/server/plugins/engine/views/components/telephonenumberfield.html +5 -0
  176. package/src/server/plugins/engine/views/components/textfield.html +5 -0
  177. package/src/server/plugins/engine/views/components/ukaddressfield.html +25 -0
  178. package/src/server/plugins/engine/views/components/yesnofield.html +5 -0
  179. package/src/server/plugins/engine/views/confirmation.html +19 -0
  180. package/src/server/plugins/engine/views/file-upload.html +45 -0
  181. package/src/server/plugins/engine/views/index.html +39 -0
  182. package/src/server/plugins/engine/views/item-delete.html +56 -0
  183. package/src/server/plugins/engine/views/layout.html +199 -0
  184. package/src/server/plugins/engine/views/partials/components.html +6 -0
  185. package/src/server/plugins/engine/views/partials/conditional-components.html +3 -0
  186. package/src/server/plugins/engine/views/partials/debug.html +44 -0
  187. package/src/server/plugins/engine/views/partials/form.html +15 -0
  188. package/src/server/plugins/engine/views/partials/heading.html +16 -0
  189. package/src/server/plugins/engine/views/partials/preview-banner.html +32 -0
  190. package/src/server/plugins/engine/views/partials/preview-banner.test.js +122 -0
  191. package/src/server/plugins/engine/views/partials/warn-missing-notification-email.html +10 -0
  192. package/src/server/plugins/engine/views/repeat-list-summary.html +53 -0
  193. package/src/server/plugins/engine/views/summary.html +50 -0
  194. package/src/server/plugins/errorPages.ts +58 -0
  195. package/src/server/plugins/nunjucks/context.js +88 -0
  196. package/src/server/plugins/nunjucks/context.test.js +142 -0
  197. package/src/server/plugins/nunjucks/enviroment.test.js +201 -0
  198. package/src/server/plugins/nunjucks/environment.js +116 -0
  199. package/src/server/plugins/nunjucks/filters/answer.js +27 -0
  200. package/src/server/plugins/nunjucks/filters/answer.test.js +89 -0
  201. package/src/server/plugins/nunjucks/filters/evaluate.js +21 -0
  202. package/src/server/plugins/nunjucks/filters/field.js +28 -0
  203. package/src/server/plugins/nunjucks/filters/field.test.js +75 -0
  204. package/src/server/plugins/nunjucks/filters/highlight.js +11 -0
  205. package/src/server/plugins/nunjucks/filters/href.js +30 -0
  206. package/src/server/plugins/nunjucks/filters/href.test.js +80 -0
  207. package/src/server/plugins/nunjucks/filters/index.js +8 -0
  208. package/src/server/plugins/nunjucks/filters/inspect.js +15 -0
  209. package/src/server/plugins/nunjucks/filters/page.js +24 -0
  210. package/src/server/plugins/nunjucks/filters/page.test.js +65 -0
  211. package/src/server/plugins/nunjucks/index.js +3 -0
  212. package/src/server/plugins/nunjucks/plugin.js +40 -0
  213. package/src/server/plugins/nunjucks/render.js +42 -0
  214. package/src/server/plugins/nunjucks/types.js +40 -0
  215. package/src/server/plugins/pulse.ts +11 -0
  216. package/src/server/plugins/router.ts +201 -0
  217. package/src/server/plugins/session.ts +28 -0
  218. package/src/server/routes/health.js +13 -0
  219. package/src/server/routes/health.test.js +35 -0
  220. package/src/server/routes/index.test.ts +125 -0
  221. package/src/server/routes/index.ts +2 -0
  222. package/src/server/routes/public.ts +47 -0
  223. package/src/server/routes/types.ts +48 -0
  224. package/src/server/schemas/index.ts +34 -0
  225. package/src/server/secure-context.js +43 -0
  226. package/src/server/services/cacheService.test.ts +277 -0
  227. package/src/server/services/cacheService.ts +138 -0
  228. package/src/server/services/httpService.test.js +491 -0
  229. package/src/server/services/httpService.ts +50 -0
  230. package/src/server/services/index.ts +1 -0
  231. package/src/server/types.ts +54 -0
  232. package/src/server/utils/notify.test.ts +37 -0
  233. package/src/server/utils/notify.ts +50 -0
  234. package/src/server/utils/secure-context/get-trust-store-certs.js +11 -0
  235. package/src/server/utils/secure-context/get-trust-store-certs.test.js +19 -0
  236. package/src/server/utils/utils.js +24 -0
  237. package/src/server/utils/utils.test.js +54 -0
  238. package/src/server/views/404.html +16 -0
  239. package/src/server/views/500.html +19 -0
  240. package/src/server/views/help/accessibility-statement.html +58 -0
  241. package/src/server/views/help/cookie-preferences.html +57 -0
  242. package/src/server/views/help/cookies.html +71 -0
  243. package/src/server/views/help/get-support.html +37 -0
  244. package/src/server/views/help/privacy-notice.html +68 -0
  245. package/src/server/views/help/terms-and-conditions.html +83 -0
  246. package/src/typings/hapi/index.d.ts +87 -0
  247. package/src/typings/hapi-tracing/index.d.ts +6 -0
  248. package/src/typings/index.d.ts +3 -0
  249. package/src/typings/joi/index.d.ts +22 -0
  250. package/.server/server/views/components/service-banner/template.test.js.map +0 -1
  251. package/.server/server/views/components/tag-env/template.test.js.map +0 -1
  252. /package/.server/server/{views → plugins/engine/views}/components/debug/macro.njk +0 -0
  253. /package/.server/server/{views → plugins/engine/views}/components/debug/template.njk +0 -0
  254. /package/.server/server/{views → plugins/engine/views}/components/service-banner/macro.njk +0 -0
  255. /package/.server/server/{views → plugins/engine/views}/components/service-banner/template.njk +0 -0
  256. /package/.server/server/{views → plugins/engine/views}/components/tag-env/macro.njk +0 -0
  257. /package/.server/server/{views → plugins/engine/views}/components/tag-env/template.njk +0 -0
  258. /package/.server/server/{views → plugins/engine/views}/confirmation.html +0 -0
  259. /package/.server/server/{views → plugins/engine/views}/layout.html +0 -0
  260. /package/.server/server/{views → plugins/engine/views}/summary.html +0 -0
package/README.md CHANGED
@@ -1,15 +1,209 @@
1
- # forms-engine
1
+ # @defra/forms-engine-plugin
2
2
 
3
- Form hapi-plugin
3
+ The `@defra/forms-engine-plugin` is a [plugin](https://hapi.dev/tutorials/plugins/?lang=en_US) for [hapi](https://hapi.dev/) used to serve GOV.UK-based form journeys.
4
4
 
5
- ...
5
+ It is designed to be embedded in the frontend of a digital service and provide a convenient, configuration driven approach to building forms that are aligned to [GDS Design System](https://design-system.service.gov.uk/) guidelines.
6
+
7
+ ## Installation
8
+
9
+ `npm install @defra/forms-engine-plugin --save`
10
+
11
+ ## Dependencies
12
+
13
+ The following are [plugin dependencies](<https://hapi.dev/api/?v=21.4.0#server.dependency()>) that are required to be registered with hapi:
14
+
15
+ `npm install hapi-pino @hapi/crumb @hapi/yar @hapi/vision --save`
16
+
17
+ - [hapi-pino](https://github.com/hapijs/hapi-pino) - [Pino](https://github.com/pinojs/pino) logger for hapi
18
+ - [@hapi/crumb](https://github.com/hapijs/crumb) - CSRF crumb generation and validation
19
+ - [@hapi/yar](https://github.com/hapijs/yar) - Session manager
20
+ - [@hapi/vision](https://github.com/hapijs/vision) - Template rendering support
21
+
22
+ Additional npm dependencies that you will need are:
23
+
24
+ `npm install nunjucks govuk-frontend --save`
25
+
26
+ - [nunjucks](https://www.npmjs.com/package/nunjucks) - [templating engine](https://mozilla.github.io/nunjucks/) used by GOV.UK design system
27
+ - [govuk-frontend](https://www.npmjs.com/package/govuk-frontend) - [code](https://github.com/alphagov/govuk-frontend) you need to build a user interface for government platforms and services
28
+
29
+ Optional dependencies
30
+
31
+ `npm install @hapi/inert --save`
32
+
33
+ - [@hapi/inert](https://www.npmjs.com/package/@hapi/inert) - static file and directory handlers for serving GOV.UK assets and styles
34
+
35
+ ## Setup
36
+
37
+ ### Form config
38
+
39
+ The `form-engine-plugin` uses JSON configuration files to serve form journeys.
40
+ These files are called `Form definitions` and are built up of:
41
+
42
+ - `pages` - includes a `path`, `title`
43
+ - `components` - one or more questions on a page
44
+ - `conditions` - used to conditionally show and hide pages and
45
+ - `lists` - data used to in selection fields like [Select](https://design-system.service.gov.uk/components/select/), [Checkboxes](https://design-system.service.gov.uk/components/checkboxes/) and [Radios](https://design-system.service.gov.uk/components/radios/)
46
+
47
+ The [types](https://github.com/DEFRA/forms-designer/blob/main/model/src/form/form-definition/types.ts), `joi` [schema](https://github.com/DEFRA/forms-designer/blob/main/model/src/form/form-definition/index.ts) and the [examples](test/form/definitions) folder are a good place to learn about the structure of these files.
48
+
49
+ TODO - Link to wiki for `Form metadata`
50
+ TODO - Link to wiki for `Form definition`
51
+
52
+ #### Providing form config to the engine
53
+
54
+ The engine plugin registers several [routes](https://hapi.dev/tutorials/routing/?lang=en_US) on the hapi server.
55
+
56
+ They look like this:
57
+
58
+ ```
59
+ GET /{slug}/{path}
60
+ POST /{slug}/{path}
61
+ ```
62
+
63
+ A unique `slug` is used to route the user to the correct form, and the `path` used to identify the correct page within the form to show.
64
+ The [plugin registration options](#options) have a `services` setting to provide a `formsService` that is responsible for returning `form definition` data.
65
+
66
+ WARNING: This below is subject to change
67
+
68
+ A `formsService` has two methods, one for returning `formMetadata` and another to return `formDefinition`s.
69
+
70
+ ```
71
+ const formsService = {
72
+ getFormMetadata: async function (slug) {
73
+ // Returns the metadata for the slug
74
+ },
75
+ getFormDefinition: async function (id, state) {
76
+ // Returns the form definition for the given id
77
+ }
78
+ }
79
+ ```
80
+
81
+ The reason for the two separate methods is caching.
82
+ `formMetadata` is a lightweight record designed to give top level information about a form.
83
+ This method is invoked for every page request.
84
+
85
+ Only when the `formMetadata` indicates that the definition has changed is a call to `getFormDefinition` is made.
86
+ The response from this can be quite big as it contains the entire form definition.
87
+
88
+ See [example](#example) below for more detail
89
+
90
+ ### Static assets and styles
91
+
92
+ TODO
93
+
94
+ ## Example
95
+
96
+ ```
97
+ import hapi from '@hapi/hapi'
98
+ import yar from '@hapi/yar'
99
+ import crumb from '@hapi/crumb'
100
+ import inert from '@hapi/inert'
101
+ import pino from 'hapi-pino'
102
+ import plugin from '@defra/forms-engine-plugin'
103
+
104
+ const server = hapi.server({
105
+ port: 3000
106
+ })
107
+
108
+ // Register the dependent plugins
109
+ await server.register(pino)
110
+ await server.register(inert)
111
+ await server.register(crumb)
112
+ await server.register({
113
+ plugin: yar,
114
+ options: {
115
+ cookieOptions: {
116
+ password: 'ENTER_YOUR_SESSION_COOKIE_PASSWORD_HERE' // Must be > 32 chars
117
+ }
118
+ }
119
+ })
120
+
121
+ // Register the `forms-engine-plugin`
122
+ await server.register({
123
+ plugin
124
+ })
125
+
126
+ await server.start()
127
+ ```
128
+
129
+ ## Environment variables
130
+
131
+ ## Options
132
+
133
+ The forms plugin is configured with [registration options](https://hapi.dev/api/?v=21.4.0#plugins)
134
+
135
+ - `services` (optional) - object containing `formsService`, `formSubmissionService` and `outputService`
136
+ - `formsService` - used to load `formMetadata` and `formDefinition`
137
+ - `formSubmissionService` - used prepare the form during submission (ignore - subject to change)
138
+ - `outputService` - used to save the submission
139
+ - `controllers` (optional) - Object map of custom page controllers used to override the default. See [custom controllers](#custom-controllers)
140
+ - `filters` (optional) - A map of custom template filters to include
141
+ - `cacheName` (optional) - The cache name to use. Defaults to hapi's [default server cache]. Recommended for production. See [here]
142
+ (#custom-cache) for more details
143
+ - `pluginPath` (optional) - The location of the plugin (defaults to `node_modules/@defra/forms-engine-plugin`)
144
+
145
+ ### Services
146
+
147
+ TODO
148
+
149
+ ### Custom controllers
150
+
151
+ TODO
152
+
153
+ ### Custom filters
154
+
155
+ Use the `filter` plugin option to provide custom template filters.
156
+ Filters are available in both [nunjucks](https://mozilla.github.io/nunjucks/templating.html#filters) and [liquid](https://liquidjs.com/filters/overview.html) templates.
157
+
158
+ ```
159
+ const formatter = new Intl.NumberFormat('en-GB')
160
+
161
+ await server.register({
162
+ plugin,
163
+ options: {
164
+ filters: {
165
+ money: value => formatter.format(value),
166
+ upper: value => typeof value === 'string' ? value.toUpperCase() : value
167
+ }
168
+ }
169
+ })
170
+ ```
171
+
172
+ ### Custom cache
173
+
174
+ The plugin will use the [default server cache](https://hapi.dev/api/?v=21.4.0#-serveroptionscache) to store form answers on the server.
175
+ This is just an in-memory cache which is fine for development.
176
+
177
+ In production you should create a custom cache one of the available `@hapi/catbox` adapters.
178
+
179
+ E.g. [Redis](https://github.com/hapijs/catbox-redis)
180
+
181
+ ```
182
+ import { Engine as CatboxRedis } from '@hapi/catbox-redis'
183
+
184
+ const server = new Hapi.Server({
185
+ cache : [
186
+ {
187
+ name: 'my_cache',
188
+ provider: {
189
+ constructor: CatboxRedis,
190
+ options: {}
191
+ }
192
+ }
193
+ ]
194
+ })
195
+ ```
196
+
197
+ ## Exemplar
198
+
199
+ TODO: Link to CDP exemplar
6
200
 
7
201
  ## Templates
8
202
 
9
203
  The following elements support [LiquidJS templates](https://liquidjs.com/):
10
204
 
11
205
  - Page **title**
12
- - Form component **titles**
206
+ - Form component **title**
13
207
  - Support for fieldset legend text or label text
14
208
  - This includes when the title is used in **error messages**
15
209
  - Html (guidance) component **content**
@@ -85,3 +279,20 @@ There are a number of `LiquidJS` filters available to you from within the templa
85
279
  }
86
280
  ]
87
281
  ```
282
+
283
+ ## Templates and views: Extending the default layout
284
+
285
+ TODO
286
+
287
+ To override the default page template, vision and nunjucks both need to be configured to search in the `forms-engine-plugin` views directory when looking for template files.
288
+
289
+ For vision this is done through the `path` [plugin option](https://github.com/hapijs/vision/blob/master/API.md#options)
290
+ For nunjucks it is configured through the environment [configure options](https://mozilla.github.io/nunjucks/api.html#configure).
291
+
292
+ The `forms-engine-plugin` path to add can be imported from:
293
+
294
+ `import { VIEW_PATH } from '@defra/forms-engine-plugin'`
295
+
296
+ Which can then be appended to the `node_modules` path `node_modules/@defra/forms-engine`.
297
+
298
+ The main template layout is `govuk-frontend`'s `template.njk` file, this also needs to be added to the `path`s that nunjucks can look in.
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@defra/forms-engine-plugin",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "Defra forms engine",
5
5
  "type": "module",
6
6
  "main": ".server/server/plugins/engine/index.js",
7
7
  "files": [
8
8
  ".server",
9
- ".public"
9
+ ".public",
10
+ "src"
10
11
  ],
11
12
  "scripts": {
12
13
  "build": "npm run build:server && npm run build:client",
@@ -59,7 +60,6 @@
59
60
  "@hapi/vision": "^7.0.3",
60
61
  "@hapi/wreck": "^18.1.0",
61
62
  "@hapi/yar": "^11.0.2",
62
- "@hapipal/schmervice": "^3.0.0",
63
63
  "@types/humanize-duration": "^3.27.4",
64
64
  "accessible-autocomplete": "^3.0.1",
65
65
  "atob": "^2.1.2",
@@ -0,0 +1,87 @@
1
+ import {
2
+ Button,
3
+ CharacterCount,
4
+ Checkboxes,
5
+ ErrorSummary,
6
+ Header,
7
+ NotificationBanner,
8
+ Radios,
9
+ SkipLink,
10
+ createAll
11
+ } from 'govuk-frontend'
12
+
13
+ createAll(Button)
14
+ createAll(CharacterCount)
15
+ createAll(Checkboxes)
16
+ createAll(ErrorSummary)
17
+ createAll(Header)
18
+ createAll(NotificationBanner)
19
+ createAll(Radios)
20
+ createAll(SkipLink)
21
+
22
+ // Show preview close link via `rel="opener"`
23
+ if (window.opener) {
24
+ const $closeLink = document.querySelector('.js-preview-banner-close')
25
+
26
+ $closeLink?.removeAttribute('hidden')
27
+ $closeLink?.addEventListener('click', (event) => {
28
+ event.preventDefault()
29
+ window.close()
30
+ })
31
+ }
32
+
33
+ /**
34
+ * Initialise autocomplete
35
+ * @param {HTMLSelectElement | null} $select
36
+ * @param {(config: object) => void} init
37
+ */
38
+ function initAutocomplete($select, init) {
39
+ if (!$select) {
40
+ return
41
+ }
42
+
43
+ const config = {
44
+ id: $select.id,
45
+ selectElement: $select
46
+ }
47
+
48
+ init(config)
49
+
50
+ /** @type {HTMLInputElement | null} */
51
+ const $input = document.querySelector(`#${config.id}`)
52
+
53
+ // Allowed values for input
54
+ const inputValues = [...$select.options].map((option) => option.text)
55
+
56
+ // Reset select when input value is not allowed
57
+ $input?.addEventListener('blur', () => {
58
+ if (!$input.value || !inputValues.includes($input.value)) {
59
+ $select.value = ''
60
+ }
61
+ })
62
+ }
63
+
64
+ // Find all autocompletes
65
+ const $autocompletes = document.querySelectorAll(
66
+ `[data-module="govuk-accessible-autocomplete"]`
67
+ )
68
+
69
+ // Lazy load autocomplete component
70
+ if ($autocompletes.length) {
71
+ // @ts-expect-error -- No types available
72
+ import('accessible-autocomplete')
73
+ .then((component) => {
74
+ const { default: accessibleAutocomplete } = component
75
+
76
+ // Initialise each autocomplete
77
+ $autocompletes.forEach(($module) =>
78
+ initAutocomplete(
79
+ $module.querySelector('select'),
80
+ accessibleAutocomplete.enhanceSelectElement
81
+ )
82
+ )
83
+ })
84
+
85
+ // eslint-disable-next-line no-console
86
+ .catch(console.error)
87
+ }