@defra/forms-engine-plugin 4.0.33 → 4.0.35

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 (78) hide show
  1. package/.server/server/constants.d.ts +1 -0
  2. package/.server/server/constants.js +1 -0
  3. package/.server/server/constants.js.map +1 -1
  4. package/.server/server/forms/register-as-a-unicorn-breeder.yaml +0 -1
  5. package/.server/server/forms/simple-form.yaml +64 -0
  6. package/.server/server/plugins/engine/beta/form-context.js +1 -2
  7. package/.server/server/plugins/engine/beta/form-context.js.map +1 -1
  8. package/.server/server/plugins/engine/components/FileUploadField.d.ts +4 -3
  9. package/.server/server/plugins/engine/components/FileUploadField.js +38 -0
  10. package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -1
  11. package/.server/server/plugins/engine/components/FormComponent.d.ts +9 -7
  12. package/.server/server/plugins/engine/components/FormComponent.js +3 -0
  13. package/.server/server/plugins/engine/components/FormComponent.js.map +1 -1
  14. package/.server/server/plugins/engine/helpers.d.ts +5 -0
  15. package/.server/server/plugins/engine/helpers.js +7 -0
  16. package/.server/server/plugins/engine/helpers.js.map +1 -1
  17. package/.server/server/plugins/engine/index.d.ts +2 -0
  18. package/.server/server/plugins/engine/index.js +2 -0
  19. package/.server/server/plugins/engine/index.js.map +1 -1
  20. package/.server/server/plugins/engine/models/FormModel.js +4 -0
  21. package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
  22. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js +6 -2
  23. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -1
  24. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +8 -3
  25. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
  26. package/.server/server/plugins/engine/pageControllers/StartPageController.d.ts +4 -0
  27. package/.server/server/plugins/engine/pageControllers/SummaryPageController.d.ts +1 -1
  28. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +33 -35
  29. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
  30. package/.server/server/plugins/engine/pageControllers/__stubs__/request.d.ts +2 -2
  31. package/.server/server/plugins/engine/pageControllers/__stubs__/request.js +9 -0
  32. package/.server/server/plugins/engine/pageControllers/__stubs__/request.js.map +1 -1
  33. package/.server/server/plugins/engine/pageControllers/errors.d.ts +15 -0
  34. package/.server/server/plugins/engine/pageControllers/errors.js +25 -0
  35. package/.server/server/plugins/engine/pageControllers/errors.js.map +1 -0
  36. package/.server/server/plugins/engine/pageControllers/helpers/state.d.ts +13 -1
  37. package/.server/server/plugins/engine/pageControllers/helpers/state.js +33 -0
  38. package/.server/server/plugins/engine/pageControllers/helpers/state.js.map +1 -1
  39. package/.server/server/plugins/engine/services/localFormsService.js +6 -0
  40. package/.server/server/plugins/engine/services/localFormsService.js.map +1 -1
  41. package/.server/server/plugins/engine/views/index.html +1 -1
  42. package/.server/server/plugins/nunjucks/context.test.js +9 -1
  43. package/.server/server/plugins/nunjucks/context.test.js.map +1 -1
  44. package/.server/server/plugins/nunjucks/types.d.ts +4 -0
  45. package/.server/server/plugins/nunjucks/types.js +1 -0
  46. package/.server/server/plugins/nunjucks/types.js.map +1 -1
  47. package/.server/server/services/cacheService.d.ts +1 -0
  48. package/.server/server/services/cacheService.js +10 -0
  49. package/.server/server/services/cacheService.js.map +1 -1
  50. package/.server/typings/hapi/index.d.js.map +1 -1
  51. package/package.json +1 -1
  52. package/src/server/constants.js +1 -0
  53. package/src/server/forms/register-as-a-unicorn-breeder.yaml +0 -1
  54. package/src/server/forms/simple-form.yaml +64 -0
  55. package/src/server/plugins/engine/beta/form-context.test.ts +4 -3
  56. package/src/server/plugins/engine/beta/form-context.ts +4 -3
  57. package/src/server/plugins/engine/components/FileUploadField.test.ts +203 -2
  58. package/src/server/plugins/engine/components/FileUploadField.ts +61 -2
  59. package/src/server/plugins/engine/components/FormComponent.ts +17 -1
  60. package/src/server/plugins/engine/helpers.ts +8 -0
  61. package/src/server/plugins/engine/index.ts +3 -0
  62. package/src/server/plugins/engine/models/FormModel.ts +4 -0
  63. package/src/server/plugins/engine/pageControllers/FileUploadPageController.test.ts +9 -0
  64. package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +11 -4
  65. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +12 -2
  66. package/src/server/plugins/engine/pageControllers/SummaryPageController.test.ts +3 -0
  67. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +55 -46
  68. package/src/server/plugins/engine/pageControllers/__stubs__/request.ts +14 -4
  69. package/src/server/plugins/engine/pageControllers/errors.test.ts +63 -0
  70. package/src/server/plugins/engine/pageControllers/errors.ts +30 -0
  71. package/src/server/plugins/engine/pageControllers/helpers/state.test.ts +75 -1
  72. package/src/server/plugins/engine/pageControllers/helpers/state.ts +50 -1
  73. package/src/server/plugins/engine/services/localFormsService.js +7 -0
  74. package/src/server/plugins/engine/views/index.html +1 -1
  75. package/src/server/plugins/nunjucks/context.test.js +10 -2
  76. package/src/server/plugins/nunjucks/types.js +1 -0
  77. package/src/server/services/cacheService.ts +16 -0
  78. package/src/typings/hapi/index.d.ts +2 -0
@@ -1,9 +1,17 @@
1
1
  import { getHiddenFields } from '@defra/forms-model'
2
2
 
3
+ import {
4
+ CURRENT_PAGE_PATH_KEY,
5
+ STATE_NOT_YET_VALIDATED
6
+ } from '~/src/server/plugins/engine/index.js'
3
7
  import { type PageControllerClass } from '~/src/server/plugins/engine/pageControllers/helpers/pages.js'
4
8
  import {
5
9
  type AnyFormRequest,
6
- type FormStateValue
10
+ type FormContext,
11
+ type FormContextRequest,
12
+ type FormStateValue,
13
+ type FormSubmissionState,
14
+ type FormValue
7
15
  } from '~/src/server/plugins/engine/types.js'
8
16
  import { type FormQuery } from '~/src/server/routes/types.js'
9
17
  import { type Services } from '~/src/server/types.js'
@@ -91,3 +99,44 @@ export async function prefillStateFromQueryParameters(
91
99
 
92
100
  return true
93
101
  }
102
+
103
+ /**
104
+ * Copies any potentially invalid state into the payload, and removes those values from state
105
+ * NOTE - this method has a side-effect on 'context.state' and 'context.payload'
106
+ * @param request - the form request
107
+ * @param context - the form context
108
+ */
109
+ export function copyNotYetValidatedState(
110
+ request: FormContextRequest,
111
+ context: FormContext
112
+ ) {
113
+ const potentiallyInvalidState = context.state[STATE_NOT_YET_VALIDATED] as
114
+ | Record<string, FormValue>
115
+ | undefined
116
+ if (!potentiallyInvalidState) {
117
+ return
118
+ }
119
+
120
+ const originalPath = potentiallyInvalidState[CURRENT_PAGE_PATH_KEY]
121
+
122
+ if (originalPath && originalPath === request.url.pathname) {
123
+ context.payload = {
124
+ ...context.payload,
125
+ ...potentiallyInvalidState,
126
+ [CURRENT_PAGE_PATH_KEY]: undefined
127
+ }
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Remove any temporary 'not yet validated' state now that it's been validated
133
+ * @param state - the form state
134
+ */
135
+ export function clearNotYetValidatedState(
136
+ state: FormSubmissionState
137
+ ): FormSubmissionState {
138
+ if (state[STATE_NOT_YET_VALIDATED]) {
139
+ state[STATE_NOT_YET_VALIDATED] = undefined
140
+ }
141
+ return state
142
+ }
@@ -51,5 +51,12 @@ export const formsService = async () => {
51
51
  slug: 'components'
52
52
  })
53
53
 
54
+ await loader.addForm('src/server/forms/simple-form.yaml', {
55
+ ...metadata,
56
+ id: 'a1b2c3d4-e5f6-7890-abcd-ef0123456789',
57
+ title: 'Simple Form',
58
+ slug: 'simple-form'
59
+ })
60
+
54
61
  return loader.toFormsService()
55
62
  }
@@ -10,7 +10,7 @@
10
10
  {% include "partials/preview-banner.html" %}
11
11
  {% endif %}
12
12
 
13
- {% if errors %}
13
+ {% if errors | length %}
14
14
  {{ govukErrorSummary({
15
15
  titleText: "There is a problem",
16
16
  errorList: checkErrorTemplates(errors)
@@ -87,7 +87,11 @@ describe('Nunjucks context', () => {
87
87
  }
88
88
  },
89
89
  path: '/test',
90
- url: { search: '' }
90
+ url: { search: '' },
91
+ yar: {
92
+ flash: jest.fn().mockReturnValue([]),
93
+ commit: jest.fn()
94
+ }
91
95
  // state intentionally omitted to test real malformed requests
92
96
  })
93
97
  )
@@ -121,7 +125,11 @@ describe('Nunjucks context', () => {
121
125
  },
122
126
  path: '/test',
123
127
  url: { search: '' },
124
- state: {}
128
+ state: {},
129
+ yar: {
130
+ flash: jest.fn().mockReturnValue([]),
131
+ commit: jest.fn()
132
+ }
125
133
  })
126
134
  )
127
135
 
@@ -17,6 +17,7 @@
17
17
  * @property {string} [currentPath] - Current path
18
18
  * @property {string} [previewMode] - Preview mode
19
19
  * @property {string} [slug] - Form slug
20
+ * @property {string} [error] - Error message for temporary error messages (not related to form state)
20
21
  * @property {FormContext} [context] - the current form context
21
22
  */
22
23
 
@@ -99,6 +99,22 @@ export class CacheService {
99
99
  request.yar.flash(key.id, message)
100
100
  }
101
101
 
102
+ async resetComponentStates(
103
+ request: AnyFormRequest,
104
+ componentNames: string[]
105
+ ) {
106
+ const state = await this.getState(request)
107
+
108
+ for (const componentName of componentNames) {
109
+ if (componentName in state) {
110
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
111
+ delete state[componentName]
112
+ }
113
+ }
114
+
115
+ return this.setState(request, state)
116
+ }
117
+
102
118
  /**
103
119
  * The key used to store user session data against.
104
120
  * If there are multiple forms on the same runner instance, for example `form-a` and `form-a-feedback` this will prevent CacheService from clearing data from `form-a` if a user gave feedback before they finished `form-a`
@@ -5,6 +5,7 @@ import { type ServerYar, type Yar } from '@hapi/yar'
5
5
  import { type Logger } from 'pino'
6
6
 
7
7
  import {
8
+ type COMPONENT_STATE_ERROR,
8
9
  type EXTERNAL_STATE_APPENDAGE,
9
10
  type EXTERNAL_STATE_PAYLOAD
10
11
  } from '~/src/server/constants.js'
@@ -20,6 +21,7 @@ declare module '@hapi/yar' {
20
21
  interface YarFlashes {
21
22
  [EXTERNAL_STATE_APPENDAGE]: object
22
23
  [EXTERNAL_STATE_PAYLOAD]: object
24
+ [COMPONENT_STATE_ERROR]: string
23
25
  [key: string]: { errors: FormSubmissionError[] }
24
26
  }
25
27
  }