@defra/forms-engine-plugin 0.0.3 → 0.0.4

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 (328) hide show
  1. package/.public/assets/fonts/bold-affa96571d-v2.woff +0 -0
  2. package/.public/assets/fonts/bold-b542beb274-v2.woff2 +0 -0
  3. package/.public/assets/fonts/light-94a07e06a1-v2.woff2 +0 -0
  4. package/.public/assets/fonts/light-f591b13f7d-v2.woff +0 -0
  5. package/.public/assets/images/favicon.ico +0 -0
  6. package/.public/assets/images/favicon.svg +1 -0
  7. package/.public/assets/images/govuk-crest.svg +1 -0
  8. package/.public/assets/images/govuk-icon-180.png +0 -0
  9. package/.public/assets/images/govuk-icon-192.png +0 -0
  10. package/.public/assets/images/govuk-icon-512.png +0 -0
  11. package/.public/assets/images/govuk-icon-mask.svg +1 -0
  12. package/.public/assets/images/govuk-opengraph-image.png +0 -0
  13. package/.public/assets/manifest.json +39 -0
  14. package/.public/assets-manifest.json +24 -0
  15. package/.public/javascripts/application.0fd8c18.min.js +3 -0
  16. package/.public/javascripts/application.0fd8c18.min.js.LICENSE.txt +58 -0
  17. package/.public/javascripts/application.0fd8c18.min.js.map +1 -0
  18. package/.public/javascripts/file-upload.b2f18f5.min.js +2 -0
  19. package/.public/javascripts/file-upload.b2f18f5.min.js.map +1 -0
  20. package/.public/javascripts/vendor/accessible-autocomplete.275d332.min.js +2 -0
  21. package/.public/javascripts/vendor/accessible-autocomplete.275d332.min.js.map +1 -0
  22. package/.public/stylesheets/application.e340021.min.css +14 -0
  23. package/.public/stylesheets/application.e340021.min.css.map +1 -0
  24. package/package.json +6 -2
  25. package/.browserslistrc +0 -16
  26. package/.editorconfig +0 -9
  27. package/.eslintrc.cjs +0 -266
  28. package/.github/dependabot.yml +0 -85
  29. package/.github/workflows/check-pull-request.yml +0 -209
  30. package/.github/workflows/pr-notifier.yml +0 -98
  31. package/.github/workflows/publish.yml +0 -111
  32. package/.husky/pre-commit +0 -1
  33. package/.lintstagedrc.js +0 -4
  34. package/.nvmrc +0 -1
  35. package/.prettierignore +0 -8
  36. package/.prettierrc.cjs +0 -26
  37. package/Dockerfile +0 -61
  38. package/Procfile +0 -1
  39. package/babel.config.cjs +0 -55
  40. package/compose/aws.env +0 -4
  41. package/compose/start-localstack.sh +0 -26
  42. package/docker-compose.yaml +0 -86
  43. package/globals.d.ts +0 -1
  44. package/jest.config.cjs +0 -54
  45. package/jest.environment.js +0 -4
  46. package/jest.setup.cjs +0 -14
  47. package/postcss.config.js +0 -26
  48. package/sonar-project.properties +0 -17
  49. package/src/client/javascripts/application.js +0 -87
  50. package/src/client/javascripts/file-upload.js +0 -386
  51. package/src/client/stylesheets/_code.scss +0 -33
  52. package/src/client/stylesheets/_govuk-frontend.scss +0 -4
  53. package/src/client/stylesheets/_prose.scss +0 -56
  54. package/src/client/stylesheets/_service-banner.scss +0 -24
  55. package/src/client/stylesheets/_summary-list.scss +0 -28
  56. package/src/client/stylesheets/_tag-env.scss +0 -24
  57. package/src/client/stylesheets/application.scss +0 -14
  58. package/src/common/cookies.js +0 -58
  59. package/src/common/cookies.test.js +0 -23
  60. package/src/common/types.js +0 -5
  61. package/src/config/index.ts +0 -271
  62. package/src/index.ts +0 -31
  63. package/src/server/common/helpers/logging/logger-options.test.ts +0 -50
  64. package/src/server/common/helpers/logging/logger-options.ts +0 -46
  65. package/src/server/common/helpers/logging/logger.ts +0 -7
  66. package/src/server/common/helpers/logging/request-logger.ts +0 -9
  67. package/src/server/common/helpers/logging/request-tracing.js +0 -10
  68. package/src/server/common/helpers/redis-client.js +0 -70
  69. package/src/server/constants.js +0 -1
  70. package/src/server/forms/README.md +0 -10
  71. package/src/server/forms/components.json +0 -1015
  72. package/src/server/forms/report-a-terrorist.json +0 -270
  73. package/src/server/forms/runner-components-test.json +0 -365
  74. package/src/server/forms/test.json +0 -581
  75. package/src/server/index.test.ts +0 -582
  76. package/src/server/index.ts +0 -140
  77. package/src/server/plugins/blankie.test.ts +0 -73
  78. package/src/server/plugins/blankie.ts +0 -48
  79. package/src/server/plugins/crumb.ts +0 -20
  80. package/src/server/plugins/engine/README.md +0 -87
  81. package/src/server/plugins/engine/components/AutocompleteField.test.ts +0 -294
  82. package/src/server/plugins/engine/components/AutocompleteField.ts +0 -49
  83. package/src/server/plugins/engine/components/CheckboxesField.test.ts +0 -379
  84. package/src/server/plugins/engine/components/CheckboxesField.ts +0 -106
  85. package/src/server/plugins/engine/components/ComponentBase.ts +0 -97
  86. package/src/server/plugins/engine/components/ComponentCollection.ts +0 -278
  87. package/src/server/plugins/engine/components/DatePartsField.test.ts +0 -822
  88. package/src/server/plugins/engine/components/DatePartsField.ts +0 -264
  89. package/src/server/plugins/engine/components/Details.test.ts +0 -49
  90. package/src/server/plugins/engine/components/Details.ts +0 -30
  91. package/src/server/plugins/engine/components/EmailAddressField.test.ts +0 -395
  92. package/src/server/plugins/engine/components/EmailAddressField.ts +0 -55
  93. package/src/server/plugins/engine/components/FileUploadField.test.ts +0 -778
  94. package/src/server/plugins/engine/components/FileUploadField.ts +0 -262
  95. package/src/server/plugins/engine/components/FormComponent.ts +0 -249
  96. package/src/server/plugins/engine/components/Html.test.ts +0 -48
  97. package/src/server/plugins/engine/components/Html.ts +0 -29
  98. package/src/server/plugins/engine/components/InsetText.test.ts +0 -48
  99. package/src/server/plugins/engine/components/InsetText.ts +0 -27
  100. package/src/server/plugins/engine/components/List.test.ts +0 -76
  101. package/src/server/plugins/engine/components/List.ts +0 -72
  102. package/src/server/plugins/engine/components/ListFormComponent.ts +0 -140
  103. package/src/server/plugins/engine/components/MonthYearField.test.ts +0 -567
  104. package/src/server/plugins/engine/components/MonthYearField.ts +0 -222
  105. package/src/server/plugins/engine/components/MultilineTextField.test.ts +0 -558
  106. package/src/server/plugins/engine/components/MultilineTextField.ts +0 -138
  107. package/src/server/plugins/engine/components/NumberField.test.ts +0 -701
  108. package/src/server/plugins/engine/components/NumberField.ts +0 -163
  109. package/src/server/plugins/engine/components/RadiosField.test.ts +0 -288
  110. package/src/server/plugins/engine/components/RadiosField.ts +0 -24
  111. package/src/server/plugins/engine/components/SelectField.test.ts +0 -288
  112. package/src/server/plugins/engine/components/SelectField.ts +0 -47
  113. package/src/server/plugins/engine/components/SelectionControlField.ts +0 -43
  114. package/src/server/plugins/engine/components/TelephoneNumberField.test.ts +0 -356
  115. package/src/server/plugins/engine/components/TelephoneNumberField.ts +0 -67
  116. package/src/server/plugins/engine/components/TextField.test.ts +0 -489
  117. package/src/server/plugins/engine/components/TextField.ts +0 -96
  118. package/src/server/plugins/engine/components/UkAddressField.test.ts +0 -623
  119. package/src/server/plugins/engine/components/UkAddressField.ts +0 -172
  120. package/src/server/plugins/engine/components/YesNoField.test.ts +0 -248
  121. package/src/server/plugins/engine/components/YesNoField.ts +0 -31
  122. package/src/server/plugins/engine/components/constants.ts +0 -1
  123. package/src/server/plugins/engine/components/helpers.ts +0 -330
  124. package/src/server/plugins/engine/components/index.ts +0 -24
  125. package/src/server/plugins/engine/components/types.ts +0 -117
  126. package/src/server/plugins/engine/configureEnginePlugin.ts +0 -47
  127. package/src/server/plugins/engine/helpers.test.ts +0 -791
  128. package/src/server/plugins/engine/helpers.ts +0 -379
  129. package/src/server/plugins/engine/index.ts +0 -7
  130. package/src/server/plugins/engine/models/FormModel.test.ts +0 -42
  131. package/src/server/plugins/engine/models/FormModel.ts +0 -443
  132. package/src/server/plugins/engine/models/RepeatingSummaryViewModel.ts +0 -0
  133. package/src/server/plugins/engine/models/Section.ts +0 -0
  134. package/src/server/plugins/engine/models/SummaryViewModel.test.ts +0 -209
  135. package/src/server/plugins/engine/models/SummaryViewModel.ts +0 -220
  136. package/src/server/plugins/engine/models/index.ts +0 -2
  137. package/src/server/plugins/engine/models/types.ts +0 -114
  138. package/src/server/plugins/engine/outputFormatters/human/v1.test.ts +0 -143
  139. package/src/server/plugins/engine/outputFormatters/human/v1.ts +0 -73
  140. package/src/server/plugins/engine/outputFormatters/index.test.ts +0 -17
  141. package/src/server/plugins/engine/outputFormatters/index.ts +0 -44
  142. package/src/server/plugins/engine/outputFormatters/machine/v1.test.ts +0 -229
  143. package/src/server/plugins/engine/outputFormatters/machine/v1.ts +0 -140
  144. package/src/server/plugins/engine/outputFormatters/machine/v2.test.ts +0 -229
  145. package/src/server/plugins/engine/outputFormatters/machine/v2.ts +0 -153
  146. package/src/server/plugins/engine/pageControllers/FileUploadPageController.test.ts +0 -1108
  147. package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +0 -446
  148. package/src/server/plugins/engine/pageControllers/PageController.test.ts +0 -205
  149. package/src/server/plugins/engine/pageControllers/PageController.ts +0 -176
  150. package/src/server/plugins/engine/pageControllers/QuestionPageController.test.ts +0 -1264
  151. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +0 -561
  152. package/src/server/plugins/engine/pageControllers/README.md +0 -28
  153. package/src/server/plugins/engine/pageControllers/RepeatPageController.test.ts +0 -264
  154. package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +0 -458
  155. package/src/server/plugins/engine/pageControllers/StartPageController.ts +0 -18
  156. package/src/server/plugins/engine/pageControllers/StatusPageController.ts +0 -50
  157. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +0 -261
  158. package/src/server/plugins/engine/pageControllers/TerminalController.test.ts +0 -28
  159. package/src/server/plugins/engine/pageControllers/TerminalPageController.ts +0 -19
  160. package/src/server/plugins/engine/pageControllers/helpers.test.ts +0 -198
  161. package/src/server/plugins/engine/pageControllers/helpers.ts +0 -101
  162. package/src/server/plugins/engine/pageControllers/index.ts +0 -10
  163. package/src/server/plugins/engine/pageControllers/validationOptions.ts +0 -89
  164. package/src/server/plugins/engine/plugin.ts +0 -673
  165. package/src/server/plugins/engine/services/formSubmissionService.js +0 -46
  166. package/src/server/plugins/engine/services/formsService.js +0 -46
  167. package/src/server/plugins/engine/services/formsService.test.js +0 -90
  168. package/src/server/plugins/engine/services/index.js +0 -3
  169. package/src/server/plugins/engine/services/notifyService.test.ts +0 -132
  170. package/src/server/plugins/engine/services/notifyService.ts +0 -64
  171. package/src/server/plugins/engine/services/uploadService.js +0 -60
  172. package/src/server/plugins/engine/types.ts +0 -315
  173. package/src/server/plugins/engine/views/components/autocompletefield.html +0 -5
  174. package/src/server/plugins/engine/views/components/checkboxesfield.html +0 -5
  175. package/src/server/plugins/engine/views/components/datepartsfield.html +0 -5
  176. package/src/server/plugins/engine/views/components/details.html +0 -6
  177. package/src/server/plugins/engine/views/components/emailaddressfield.html +0 -5
  178. package/src/server/plugins/engine/views/components/fileuploadfield-key.html +0 -8
  179. package/src/server/plugins/engine/views/components/fileuploadfield-value.html +0 -3
  180. package/src/server/plugins/engine/views/components/fileuploadfield.html +0 -24
  181. package/src/server/plugins/engine/views/components/html.html +0 -3
  182. package/src/server/plugins/engine/views/components/insettext.html +0 -7
  183. package/src/server/plugins/engine/views/components/list.html +0 -36
  184. package/src/server/plugins/engine/views/components/monthyearfield.html +0 -5
  185. package/src/server/plugins/engine/views/components/multilinetextfield.html +0 -10
  186. package/src/server/plugins/engine/views/components/numberfield.html +0 -5
  187. package/src/server/plugins/engine/views/components/radiosfield.html +0 -5
  188. package/src/server/plugins/engine/views/components/selectfield.html +0 -5
  189. package/src/server/plugins/engine/views/components/telephonenumberfield.html +0 -5
  190. package/src/server/plugins/engine/views/components/textfield.html +0 -5
  191. package/src/server/plugins/engine/views/components/ukaddressfield.html +0 -25
  192. package/src/server/plugins/engine/views/components/yesnofield.html +0 -5
  193. package/src/server/plugins/engine/views/file-upload.html +0 -45
  194. package/src/server/plugins/engine/views/index.html +0 -39
  195. package/src/server/plugins/engine/views/item-delete.html +0 -56
  196. package/src/server/plugins/engine/views/partials/components.html +0 -6
  197. package/src/server/plugins/engine/views/partials/conditional-components.html +0 -3
  198. package/src/server/plugins/engine/views/partials/debug.html +0 -44
  199. package/src/server/plugins/engine/views/partials/form.html +0 -15
  200. package/src/server/plugins/engine/views/partials/heading.html +0 -16
  201. package/src/server/plugins/engine/views/partials/preview-banner.html +0 -32
  202. package/src/server/plugins/engine/views/partials/preview-banner.test.js +0 -122
  203. package/src/server/plugins/engine/views/partials/warn-missing-notification-email.html +0 -10
  204. package/src/server/plugins/engine/views/repeat-list-summary.html +0 -53
  205. package/src/server/plugins/errorPages.ts +0 -58
  206. package/src/server/plugins/nunjucks/context.js +0 -88
  207. package/src/server/plugins/nunjucks/context.test.js +0 -142
  208. package/src/server/plugins/nunjucks/enviroment.test.js +0 -201
  209. package/src/server/plugins/nunjucks/environment.js +0 -116
  210. package/src/server/plugins/nunjucks/filters/answer.js +0 -27
  211. package/src/server/plugins/nunjucks/filters/answer.test.js +0 -89
  212. package/src/server/plugins/nunjucks/filters/evaluate.js +0 -21
  213. package/src/server/plugins/nunjucks/filters/field.js +0 -28
  214. package/src/server/plugins/nunjucks/filters/field.test.js +0 -75
  215. package/src/server/plugins/nunjucks/filters/highlight.js +0 -11
  216. package/src/server/plugins/nunjucks/filters/href.js +0 -30
  217. package/src/server/plugins/nunjucks/filters/href.test.js +0 -80
  218. package/src/server/plugins/nunjucks/filters/index.js +0 -8
  219. package/src/server/plugins/nunjucks/filters/inspect.js +0 -15
  220. package/src/server/plugins/nunjucks/filters/page.js +0 -24
  221. package/src/server/plugins/nunjucks/filters/page.test.js +0 -65
  222. package/src/server/plugins/nunjucks/index.js +0 -3
  223. package/src/server/plugins/nunjucks/plugin.js +0 -40
  224. package/src/server/plugins/nunjucks/render.js +0 -42
  225. package/src/server/plugins/nunjucks/types.js +0 -40
  226. package/src/server/plugins/pulse.ts +0 -11
  227. package/src/server/plugins/router.ts +0 -201
  228. package/src/server/plugins/session.ts +0 -28
  229. package/src/server/routes/health.js +0 -13
  230. package/src/server/routes/health.test.js +0 -35
  231. package/src/server/routes/index.test.ts +0 -125
  232. package/src/server/routes/index.ts +0 -2
  233. package/src/server/routes/public.ts +0 -47
  234. package/src/server/routes/types.ts +0 -48
  235. package/src/server/schemas/index.ts +0 -34
  236. package/src/server/secure-context.js +0 -43
  237. package/src/server/services/cacheService.test.ts +0 -276
  238. package/src/server/services/cacheService.ts +0 -131
  239. package/src/server/services/httpService.test.js +0 -491
  240. package/src/server/services/httpService.ts +0 -50
  241. package/src/server/services/index.ts +0 -1
  242. package/src/server/types.ts +0 -54
  243. package/src/server/utils/notify.test.ts +0 -37
  244. package/src/server/utils/notify.ts +0 -50
  245. package/src/server/utils/secure-context/get-trust-store-certs.js +0 -11
  246. package/src/server/utils/secure-context/get-trust-store-certs.test.js +0 -19
  247. package/src/server/utils/utils.js +0 -24
  248. package/src/server/utils/utils.test.js +0 -54
  249. package/src/server/views/404.html +0 -16
  250. package/src/server/views/500.html +0 -19
  251. package/src/server/views/components/debug/macro.njk +0 -3
  252. package/src/server/views/components/debug/template.njk +0 -13
  253. package/src/server/views/components/service-banner/macro.njk +0 -3
  254. package/src/server/views/components/service-banner/template.njk +0 -20
  255. package/src/server/views/components/service-banner/template.test.js +0 -43
  256. package/src/server/views/components/tag-env/macro.njk +0 -3
  257. package/src/server/views/components/tag-env/template.njk +0 -30
  258. package/src/server/views/components/tag-env/template.test.js +0 -66
  259. package/src/server/views/confirmation.html +0 -19
  260. package/src/server/views/help/accessibility-statement.html +0 -58
  261. package/src/server/views/help/cookie-preferences.html +0 -57
  262. package/src/server/views/help/cookies.html +0 -71
  263. package/src/server/views/help/get-support.html +0 -37
  264. package/src/server/views/help/privacy-notice.html +0 -68
  265. package/src/server/views/help/terms-and-conditions.html +0 -83
  266. package/src/server/views/layout.html +0 -199
  267. package/src/server/views/summary.html +0 -50
  268. package/src/typings/hapi/index.d.ts +0 -95
  269. package/src/typings/hapi-tracing/index.d.ts +0 -6
  270. package/src/typings/index.d.ts +0 -3
  271. package/src/typings/joi/index.d.ts +0 -22
  272. package/stylelint.config.js +0 -10
  273. package/test/client/javascripts/file-upload.test.js +0 -1197
  274. package/test/condition/checkboxes.test.js +0 -112
  275. package/test/condition/radios.test.js +0 -112
  276. package/test/condition/text.test.js +0 -103
  277. package/test/fixtures/assets-manifest.json +0 -4
  278. package/test/fixtures/form.js +0 -86
  279. package/test/fixtures/index.js +0 -2
  280. package/test/fixtures/list.js +0 -92
  281. package/test/form/cookies.test.js +0 -338
  282. package/test/form/csrf.test.js +0 -87
  283. package/test/form/definitions/basic.js +0 -101
  284. package/test/form/definitions/blank.js +0 -10
  285. package/test/form/definitions/checkboxes.json +0 -88
  286. package/test/form/definitions/components.json +0 -452
  287. package/test/form/definitions/conditional-reveal.js +0 -140
  288. package/test/form/definitions/conditions-basic.js +0 -187
  289. package/test/form/definitions/conditions-complex.js +0 -338
  290. package/test/form/definitions/conditions-dates.js +0 -78
  291. package/test/form/definitions/conditions-escaping.js +0 -143
  292. package/test/form/definitions/demo-cph-number.js +0 -3099
  293. package/test/form/definitions/feedback.json +0 -45
  294. package/test/form/definitions/fields-optional.js +0 -402
  295. package/test/form/definitions/fields-required.js +0 -402
  296. package/test/form/definitions/file-upload-basic.js +0 -44
  297. package/test/form/definitions/file-upload.js +0 -66
  298. package/test/form/definitions/minimal.js +0 -39
  299. package/test/form/definitions/phase-alpha.json +0 -33
  300. package/test/form/definitions/phase-default.json +0 -26
  301. package/test/form/definitions/radios.json +0 -88
  302. package/test/form/definitions/repeat-mixed.js +0 -54
  303. package/test/form/definitions/repeat.js +0 -70
  304. package/test/form/definitions/status.json +0 -126
  305. package/test/form/definitions/templates.js +0 -183
  306. package/test/form/definitions/test.json +0 -581
  307. package/test/form/definitions/text.json +0 -75
  308. package/test/form/definitions/titles.json +0 -170
  309. package/test/form/definitions.test.js +0 -47
  310. package/test/form/exit-page.test.js +0 -210
  311. package/test/form/feedback.test.js +0 -68
  312. package/test/form/fields-optional.test.js +0 -237
  313. package/test/form/fields-required.test.js +0 -294
  314. package/test/form/file-upload.test.js +0 -313
  315. package/test/form/govuk-notify.test.js +0 -449
  316. package/test/form/journey-basic.test.js +0 -444
  317. package/test/form/persist-files.test.js +0 -227
  318. package/test/form/phase-banner.test.js +0 -71
  319. package/test/form/repeat.test.js +0 -628
  320. package/test/form/summary-submission-email.test.js +0 -95
  321. package/test/form/template.test.js +0 -288
  322. package/test/form/titles.test.js +0 -204
  323. package/test/helpers/component-helpers.js +0 -74
  324. package/test/utils/get-cookie.js +0 -42
  325. package/test/utils/get-form-definitions.js +0 -18
  326. package/tmp.pdf +0 -1
  327. package/tsconfig.json +0 -28
  328. package/webpack.config.js +0 -208
@@ -1,262 +0,0 @@
1
- import { type FileUploadFieldComponent } from '@defra/forms-model'
2
- import joi, { type ArraySchema } from 'joi'
3
-
4
- import {
5
- FormComponent,
6
- isUploadState
7
- } from '~/src/server/plugins/engine/components/FormComponent.js'
8
- import {
9
- FileStatus,
10
- UploadStatus,
11
- type FileState,
12
- type FileUpload,
13
- type FileUploadMetadata,
14
- type FormPayload,
15
- type FormState,
16
- type FormStateValue,
17
- type FormSubmissionError,
18
- type FormSubmissionState,
19
- type SummaryList,
20
- type SummaryListAction,
21
- type SummaryListRow,
22
- type UploadState,
23
- type UploadStatusFileResponse,
24
- type UploadStatusResponse
25
- } from '~/src/server/plugins/engine/types.js'
26
- import { render } from '~/src/server/plugins/nunjucks/index.js'
27
- import { type FormQuery } from '~/src/server/routes/types.js'
28
-
29
- export const uploadIdSchema = joi.string().uuid().required()
30
-
31
- export const fileSchema = joi
32
- .object<FileUpload>({
33
- fileId: joi.string().uuid().required(),
34
- filename: joi.string().required(),
35
- contentLength: joi.number().required()
36
- })
37
- .required()
38
-
39
- export const tempFileSchema = fileSchema.append({
40
- fileStatus: joi
41
- .string()
42
- .valid(FileStatus.complete, FileStatus.rejected, FileStatus.pending)
43
- .required(),
44
- errorMessage: joi.string().optional()
45
- })
46
-
47
- export const formFileSchema = fileSchema.append({
48
- fileStatus: joi.string().valid(FileStatus.complete).required()
49
- })
50
-
51
- export const metadataSchema = joi
52
- .object<FileUploadMetadata>()
53
- .keys({
54
- retrievalKey: joi.string().email().required()
55
- })
56
- .required()
57
-
58
- export const tempStatusSchema = joi
59
- .object<UploadStatusFileResponse>({
60
- uploadStatus: joi
61
- .string()
62
- .valid(UploadStatus.ready, UploadStatus.pending)
63
- .required(),
64
- metadata: metadataSchema,
65
- form: joi.object().required().keys({
66
- file: tempFileSchema
67
- }),
68
- numberOfRejectedFiles: joi.number().optional()
69
- })
70
- .required()
71
-
72
- export const formStatusSchema = joi
73
- .object<UploadStatusResponse>({
74
- uploadStatus: joi.string().valid(UploadStatus.ready).required(),
75
- metadata: metadataSchema,
76
- form: joi.object().required().keys({
77
- file: formFileSchema
78
- }),
79
- numberOfRejectedFiles: joi.number().valid(0).required()
80
- })
81
- .required()
82
-
83
- export const itemSchema = joi.object<FileState>({
84
- uploadId: uploadIdSchema
85
- })
86
-
87
- export const tempItemSchema = itemSchema.append({
88
- status: tempStatusSchema
89
- })
90
-
91
- export const formItemSchema = itemSchema.append({
92
- status: formStatusSchema
93
- })
94
-
95
- export class FileUploadField extends FormComponent {
96
- declare options: FileUploadFieldComponent['options']
97
- declare schema: FileUploadFieldComponent['schema']
98
- declare formSchema: ArraySchema<FileState>
99
- declare stateSchema: ArraySchema<FileState>
100
-
101
- constructor(
102
- def: FileUploadFieldComponent,
103
- props: ConstructorParameters<typeof FormComponent>[1]
104
- ) {
105
- super(def, props)
106
-
107
- const { options, schema, title } = def
108
-
109
- let formSchema = joi.array<FileState>().label(title).single().required()
110
-
111
- if (options.required === false) {
112
- formSchema = formSchema.optional()
113
- }
114
-
115
- if (typeof schema.length !== 'number') {
116
- if (typeof schema.max === 'number') {
117
- formSchema = formSchema.max(schema.max)
118
- }
119
-
120
- if (typeof schema.min === 'number') {
121
- formSchema = formSchema.min(schema.min)
122
- }
123
- } else {
124
- formSchema = formSchema.length(schema.length)
125
- }
126
-
127
- this.formSchema = formSchema.items(formItemSchema)
128
- this.stateSchema = formSchema
129
- .items(formItemSchema)
130
- .default(null)
131
- .allow(null)
132
-
133
- this.options = options
134
- this.schema = schema
135
- }
136
-
137
- getFormValueFromState(state: FormSubmissionState) {
138
- const { name } = this
139
- return this.getFormValue(state[name])
140
- }
141
-
142
- getFormValue(value?: FormStateValue | FormState) {
143
- return this.isValue(value) ? value : undefined
144
- }
145
-
146
- getDisplayStringFromState(state: FormSubmissionState) {
147
- const files = this.getFormValueFromState(state)
148
- if (!files?.length) {
149
- return ''
150
- }
151
-
152
- const unit = files.length === 1 ? 'file' : 'files'
153
- return `Uploaded ${files.length} ${unit}`
154
- }
155
-
156
- getContextValueFromState(state: FormSubmissionState) {
157
- const files = this.getFormValueFromState(state)
158
- return files?.map(({ status }) => status.form.file.fileId) ?? null
159
- }
160
-
161
- getViewModel(
162
- payload: FormPayload,
163
- errors?: FormSubmissionError[],
164
- query: FormQuery = {}
165
- ) {
166
- const { options, page } = this
167
-
168
- // Allow preview URL direct access
169
- const isForceAccess = 'force' in query
170
-
171
- const viewModel = super.getViewModel(payload, errors)
172
- const { attributes, id, value } = viewModel
173
-
174
- const files = this.getFormValue(value) ?? []
175
- const filtered = files.filter(
176
- (file) => file.status.form.file.fileStatus === FileStatus.complete
177
- )
178
- const count = filtered.length
179
-
180
- const rows: SummaryListRow[] = filtered.map((item, index) => {
181
- const { status } = item
182
- const { form } = status
183
- const { file } = form
184
-
185
- const tag = { classes: 'govuk-tag--green', text: 'Uploaded' }
186
-
187
- const valueHtml = render
188
- .view('components/fileuploadfield-value.html', {
189
- context: { params: { tag } }
190
- })
191
- .trim()
192
-
193
- const keyHtml = render
194
- .view('components/fileuploadfield-key.html', {
195
- context: {
196
- params: {
197
- name: file.filename,
198
- errorMessage: errors && file.errorMessage
199
- }
200
- }
201
- })
202
- .trim()
203
-
204
- const items: SummaryListAction[] = []
205
-
206
- // Remove summary list actions from previews
207
- if (!isForceAccess) {
208
- const path = `/${item.uploadId}/confirm-delete`
209
- const href = page?.getHref(`${page.path}${path}`) ?? '#'
210
-
211
- items.push({
212
- href,
213
- text: 'Remove',
214
- classes: 'govuk-link--no-visited-state',
215
- attributes: { id: `${id}__${index}` },
216
- visuallyHiddenText: file.filename
217
- })
218
- }
219
-
220
- return {
221
- key: {
222
- html: keyHtml
223
- },
224
- value: {
225
- html: valueHtml
226
- },
227
- actions: {
228
- items
229
- }
230
- } satisfies SummaryListRow
231
- })
232
-
233
- // Set up the `accept` attribute
234
- if ('accept' in options) {
235
- attributes.accept = options.accept
236
- }
237
-
238
- const summaryList: SummaryList = {
239
- classes: 'govuk-summary-list--long-key',
240
- rows
241
- }
242
-
243
- return {
244
- ...viewModel,
245
-
246
- // File input can't have a initial value
247
- value: '',
248
-
249
- // Override the component name we send to CDP
250
- name: 'file',
251
-
252
- upload: {
253
- count,
254
- summaryList
255
- }
256
- }
257
- }
258
-
259
- isValue(value?: FormStateValue | FormState): value is UploadState {
260
- return isUploadState(value)
261
- }
262
- }
@@ -1,249 +0,0 @@
1
- import { type FormComponentsDef, type Item } from '@defra/forms-model'
2
-
3
- import { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'
4
- import { optionalText } from '~/src/server/plugins/engine/components/constants.js'
5
- import {
6
- type FileState,
7
- type FormPayload,
8
- type FormState,
9
- type FormStateValue,
10
- type FormSubmissionError,
11
- type FormSubmissionState,
12
- type FormValue,
13
- type RepeatItemState,
14
- type RepeatListState,
15
- type UploadState
16
- } from '~/src/server/plugins/engine/types.js'
17
-
18
- export class FormComponent extends ComponentBase {
19
- type: FormComponentsDef['type']
20
- hint: FormComponentsDef['hint']
21
-
22
- isFormComponent = true
23
-
24
- constructor(
25
- def: FormComponentsDef,
26
- props: ConstructorParameters<typeof ComponentBase>[1]
27
- ) {
28
- super(def, props)
29
-
30
- const { hint, type } = def
31
-
32
- this.type = type
33
- this.hint = hint
34
- }
35
-
36
- get keys() {
37
- const { collection, name } = this
38
-
39
- if (collection) {
40
- const { fields } = collection
41
- return [name, ...fields.map(({ name }) => name)]
42
- }
43
-
44
- return [name]
45
- }
46
-
47
- getFormDataFromState(state: FormSubmissionState): FormPayload {
48
- const { collection, name } = this
49
-
50
- if (collection) {
51
- return collection.getFormDataFromState(state)
52
- }
53
-
54
- return {
55
- [name]: this.getFormValue(state[name])
56
- }
57
- }
58
-
59
- getFormValueFromState(state: FormSubmissionState): FormValue | FormPayload {
60
- const { collection, name } = this
61
-
62
- if (collection) {
63
- return collection.getFormValueFromState(state)
64
- }
65
-
66
- return this.getFormValue(state[name])
67
- }
68
-
69
- getFormValue(value?: FormStateValue | FormState) {
70
- return this.isValue(value) ? value : undefined
71
- }
72
-
73
- getStateFromValidForm(payload: FormPayload): FormState {
74
- const { collection, name } = this
75
-
76
- if (collection) {
77
- return collection.getStateFromValidForm(payload)
78
- }
79
-
80
- return {
81
- [name]: this.getFormValue(payload[name]) ?? null
82
- }
83
- }
84
-
85
- getErrors(errors?: FormSubmissionError[]): FormSubmissionError[] | undefined {
86
- const { name } = this
87
-
88
- // Filter component and child errors only
89
- const list = errors?.filter(
90
- (error) =>
91
- error.name === name ||
92
- error.path.includes(name) ||
93
- this.keys.includes(error.name)
94
- )
95
-
96
- if (!list?.length) {
97
- return
98
- }
99
-
100
- return list
101
- }
102
-
103
- getError(errors?: FormSubmissionError[]): FormSubmissionError | undefined {
104
- return this.getErrors(errors)?.[0]
105
- }
106
-
107
- getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {
108
- const { hint, name, options = {}, title, viewModel } = this
109
-
110
- const isRequired = !('required' in options) || options.required !== false
111
- const hideOptional = 'optionalText' in options && options.optionalText
112
- const label = `${title}${!isRequired && !hideOptional ? optionalText : ''}`
113
-
114
- if (hint) {
115
- viewModel.hint = {
116
- text: hint
117
- }
118
- }
119
-
120
- // Filter component errors only
121
- const componentErrors = this.getErrors(errors)
122
- const componentError = this.getError(componentErrors)
123
-
124
- if (componentErrors) {
125
- viewModel.errors = componentErrors
126
- }
127
-
128
- if (componentError) {
129
- viewModel.errorMessage = {
130
- text: componentError.text
131
- }
132
- }
133
-
134
- return {
135
- ...viewModel,
136
- label: {
137
- text: label
138
- },
139
- id: name,
140
- name,
141
- value: payload[name]
142
- }
143
- }
144
-
145
- getDisplayStringFromState(state: FormSubmissionState): string {
146
- const value = this.getFormValueFromState(state)
147
- return this.isValue(value) ? value.toString() : ''
148
- }
149
-
150
- getContextValueFromState(
151
- state: FormSubmissionState
152
- ): Item['value'] | Item['value'][] | null {
153
- const value = this.getFormValueFromState(state)
154
-
155
- // Filter object field values
156
- if (this.isState(value)) {
157
- const values = Object.values(value).filter(isFormValue)
158
- return values.length ? values : null
159
- }
160
-
161
- // Filter array field values
162
- if (this.isValue(value) && Array.isArray(value)) {
163
- return value.filter(isFormValue)
164
- }
165
-
166
- return this.isValue(value) ? value : null
167
- }
168
-
169
- isValue(
170
- value?: FormStateValue | FormState
171
- ): value is NonNullable<FormStateValue> {
172
- return isFormValue(value)
173
- }
174
-
175
- isState(value?: FormStateValue | FormState): value is FormState {
176
- return isFormState(value)
177
- }
178
- }
179
-
180
- /**
181
- * Check for form value
182
- */
183
- export function isFormValue(
184
- value?: unknown
185
- ): value is string | number | boolean {
186
- return (
187
- (typeof value === 'string' && value.length > 0) ||
188
- typeof value === 'number' ||
189
- typeof value === 'boolean'
190
- )
191
- }
192
-
193
- /**
194
- * Check for form state with nested values
195
- */
196
- export function isFormState(value?: unknown): value is FormState {
197
- if (value === null || typeof value !== 'object' || Array.isArray(value)) {
198
- return false
199
- }
200
-
201
- // Skip empty objects
202
- return !!Object.values(value).length
203
- }
204
-
205
- /**
206
- * Check for repeat list state
207
- */
208
- export function isRepeatState(value?: unknown): value is RepeatListState {
209
- if (!Array.isArray(value)) {
210
- return false
211
- }
212
-
213
- // Skip checks when empty
214
- if (!value.length) {
215
- return true
216
- }
217
-
218
- return value.every(isRepeatValue)
219
- }
220
-
221
- /**
222
- * Check for repeat list value
223
- */
224
- export function isRepeatValue(value?: unknown): value is RepeatItemState {
225
- return isFormState(value) && typeof value.itemId === 'string'
226
- }
227
-
228
- /**
229
- * Check for upload state
230
- */
231
- export function isUploadState(value?: unknown): value is UploadState {
232
- if (!Array.isArray(value)) {
233
- return false
234
- }
235
-
236
- // Skip checks when empty
237
- if (!value.length) {
238
- return true
239
- }
240
-
241
- return value.every(isUploadValue)
242
- }
243
-
244
- /**
245
- * Check for upload state value
246
- */
247
- export function isUploadValue(value?: unknown): value is FileState {
248
- return isFormState(value) && typeof value.uploadId === 'string'
249
- }
@@ -1,48 +0,0 @@
1
- import { ComponentType, type HtmlComponent } from '@defra/forms-model'
2
-
3
- import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'
4
- import { type Guidance } from '~/src/server/plugins/engine/components/helpers.js'
5
- import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js'
6
- import definition from '~/test/form/definitions/basic.js'
7
-
8
- describe('HTML', () => {
9
- let model: FormModel
10
-
11
- beforeEach(() => {
12
- model = new FormModel(definition, {
13
- basePath: 'test'
14
- })
15
- })
16
-
17
- describe('Defaults', () => {
18
- let def: HtmlComponent
19
- let collection: ComponentCollection
20
- let guidance: Guidance
21
-
22
- beforeEach(() => {
23
- def = {
24
- title: 'HTML guidance',
25
- name: 'myComponent',
26
- type: ComponentType.Html,
27
- content: '<p class="govuk-body">\nLorem ipsum dolor sit amet</p>',
28
- options: {}
29
- } satisfies HtmlComponent
30
-
31
- collection = new ComponentCollection([def], { model })
32
- guidance = collection.guidance[0]
33
- })
34
-
35
- describe('View model', () => {
36
- it('sets Nunjucks component defaults', () => {
37
- const viewModel = guidance.getViewModel()
38
-
39
- expect(viewModel).toEqual(
40
- expect.objectContaining({
41
- attributes: {},
42
- content: def.content
43
- })
44
- )
45
- })
46
- })
47
- })
48
- })
@@ -1,29 +0,0 @@
1
- import { type HtmlComponent } from '@defra/forms-model'
2
-
3
- import { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'
4
-
5
- export class Html extends ComponentBase {
6
- declare options: HtmlComponent['options']
7
- content: HtmlComponent['content']
8
-
9
- constructor(
10
- def: HtmlComponent,
11
- props: ConstructorParameters<typeof ComponentBase>[1]
12
- ) {
13
- super(def, props)
14
-
15
- const { content, options } = def
16
-
17
- this.content = content
18
- this.options = options
19
- }
20
-
21
- getViewModel() {
22
- const { content, viewModel } = this
23
-
24
- return {
25
- ...viewModel,
26
- content
27
- }
28
- }
29
- }
@@ -1,48 +0,0 @@
1
- import { ComponentType, type InsetTextComponent } from '@defra/forms-model'
2
-
3
- import { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'
4
- import { type Guidance } from '~/src/server/plugins/engine/components/helpers.js'
5
- import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js'
6
- import definition from '~/test/form/definitions/basic.js'
7
-
8
- describe('InsetText', () => {
9
- let model: FormModel
10
-
11
- beforeEach(() => {
12
- model = new FormModel(definition, {
13
- basePath: 'test'
14
- })
15
- })
16
-
17
- describe('Defaults', () => {
18
- let def: InsetTextComponent
19
- let collection: ComponentCollection
20
- let guidance: Guidance
21
-
22
- beforeEach(() => {
23
- def = {
24
- title: 'Inset text guidance',
25
- name: 'myComponent',
26
- type: ComponentType.InsetText,
27
- content: 'Lorem ipsum dolor sit amet',
28
- options: {}
29
- } satisfies InsetTextComponent
30
-
31
- collection = new ComponentCollection([def], { model })
32
- guidance = collection.guidance[0]
33
- })
34
-
35
- describe('View model', () => {
36
- it('sets Nunjucks component defaults', () => {
37
- const viewModel = guidance.getViewModel()
38
-
39
- expect(viewModel).toEqual(
40
- expect.objectContaining({
41
- attributes: {},
42
- content: def.content
43
- })
44
- )
45
- })
46
- })
47
- })
48
- })
@@ -1,27 +0,0 @@
1
- import { type InsetTextComponent } from '@defra/forms-model'
2
-
3
- import { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'
4
-
5
- export class InsetText extends ComponentBase {
6
- content: InsetTextComponent['content']
7
-
8
- constructor(
9
- def: InsetTextComponent,
10
- props: ConstructorParameters<typeof ComponentBase>[1]
11
- ) {
12
- super(def, props)
13
-
14
- const { content } = def
15
-
16
- this.content = content
17
- }
18
-
19
- getViewModel() {
20
- const { content, viewModel } = this
21
-
22
- return {
23
- ...viewModel,
24
- content
25
- }
26
- }
27
- }