@planning-inspectorate/dynamic-forms 3.18.1 → 3.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planning-inspectorate/dynamic-forms",
3
- "version": "3.18.1",
3
+ "version": "3.19.1",
4
4
  "description": "This package is for building GDS forms using a configuration-based approach.",
5
5
  "main": "./src/index.js",
6
6
  "type": "module",
@@ -26,13 +26,15 @@ export class DatePeriodQuestion extends Question {
26
26
  [x: string]: any;
27
27
  };
28
28
  /**
29
- * returns the formatted answers values to be used to build task list elements
29
+ * Formats the start/end date period for display in the summary.
30
+ *
31
+ * @param {{start?: string|Date, end?: string|Date}} answer
32
+ * @returns {string}
30
33
  */
31
- formatAnswerForSummary(sectionSegment: any, journey: any, answer: any): {
32
- key: string;
33
- value: string;
34
- action: import("#typedefs/question-types.d.ts").ActionView | import("#typedefs/question-types.d.ts").ActionView[] | undefined;
35
- }[];
34
+ formatAnswer(answer: {
35
+ start?: string | Date;
36
+ end?: string | Date;
37
+ }): string;
36
38
  }
37
39
  export default DatePeriodQuestion;
38
40
  import { Question } from '#question';
@@ -1 +1 @@
1
- {"version":3,"file":"question.d.ts","sourceRoot":"","sources":["question.js"],"names":[],"mappings":"AAOA;;;GAGG;AACH;IACC;;OAEG;IACH,mGAFW,OAAO,+BAA+B,EAAE,wBAAwB,EAuB1E;IAPA,mBAA4B;IAC5B;;;MAAsD;IAEtD,8BAA0B;IAC1B,4BAAsB;IACtB,kEAA+D;IAC/D,gEAA2D;IAkB5D;;;;;OAKG,CACH,mBAJW,OAAO,SAAS,EAAE,OAAO,mBACzB,OAAO,mBAAmB,EAAE,eAAe,GACzC,OAAO,CAAE,MAAM,CAAC,CAgC5B;IAED;;MAuCC;IAWD;;OAEG;IACH;;;;QAyBC;CACD;;yBAzKwB,WAAW"}
1
+ {"version":3,"file":"question.d.ts","sourceRoot":"","sources":["question.js"],"names":[],"mappings":"AAOA;;;GAGG;AACH;IACC;;OAEG;IACH,mGAFW,OAAO,+BAA+B,EAAE,wBAAwB,EAuB1E;IAPA,mBAA4B;IAC5B;;;MAAsD;IAEtD,8BAA0B;IAC1B,4BAAsB;IACtB,kEAA+D;IAC/D,gEAA2D;IAkB5D;;;;;OAKG,CACH,mBAJW,OAAO,SAAS,EAAE,OAAO,mBACzB,OAAO,mBAAmB,EAAE,eAAe,GACzC,OAAO,CAAE,MAAM,CAAC,CAgC5B;IAED;;MAuCC;IAWD;;;;;OAKG;IACH,qBAHW;QAAC,KAAK,CAAC,EAAE,MAAM,GAAC,IAAI,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,GAAC,IAAI,CAAA;KAAC,GACtC,MAAM,CAoBlB;CACD;;yBArKwB,WAAW"}
@@ -140,33 +140,29 @@ export class DatePeriodQuestion extends Question {
140
140
  }
141
141
 
142
142
  /**
143
- * returns the formatted answers values to be used to build task list elements
143
+ * Formats the start/end date period for display in the summary.
144
+ *
145
+ * @param {{start?: string|Date, end?: string|Date}} answer
146
+ * @returns {string}
144
147
  */
145
- formatAnswerForSummary(sectionSegment, journey, answer) {
146
- let formattedAnswer;
148
+ formatAnswer(answer) {
149
+ if (!answer) {
150
+ return this.notStartedText;
151
+ }
147
152
 
148
- if (answer) {
149
- const start = answer.start && formatDateForDisplay(answer.start, { format: this.dateFormat });
150
- const end = answer.end && formatDateForDisplay(answer.end, { format: this.dateFormat });
151
- formattedAnswer = '';
152
- if (start) {
153
- formattedAnswer += `${this.labels.start}: ${start}`;
154
- if (end) {
155
- formattedAnswer += `\n`;
156
- }
157
- }
153
+ const start = answer.start && formatDateForDisplay(answer.start, { format: this.dateFormat });
154
+ const end = answer.end && formatDateForDisplay(answer.end, { format: this.dateFormat });
155
+ let formattedAnswer = '';
156
+ if (start) {
157
+ formattedAnswer += `${this.labels.start}: ${start}`;
158
158
  if (end) {
159
- formattedAnswer += `${this.labels.end}: ${end}`;
159
+ formattedAnswer += `\n`;
160
160
  }
161
- formattedAnswer = nl2br(escape(formattedAnswer));
162
- } else {
163
- formattedAnswer = this.notStartedText;
164
161
  }
165
-
166
- const action = this.getAction(sectionSegment, journey, answer);
167
- const key = this.title ?? this.question;
168
-
169
- return [{ key: key, value: formattedAnswer, action: action }];
162
+ if (end) {
163
+ formattedAnswer += `${this.labels.end}: ${end}`;
164
+ }
165
+ return nl2br(escape(formattedAnswer));
170
166
  }
171
167
  }
172
168
 
@@ -258,7 +258,7 @@ describe('DatePeriodQuestion', () => {
258
258
  });
259
259
  });
260
260
 
261
- describe('formatAnswerForSummary', () => {
261
+ describe('formatAnswer', () => {
262
262
  it('should return correctly formatted answer if it exists', () => {
263
263
  const dateQuestion = new DatePeriodQuestion({
264
264
  title: TITLE,
@@ -274,22 +274,12 @@ describe('DatePeriodQuestion', () => {
274
274
  start: new Date('2023-01-01T00:00:00.000Z'),
275
275
  end: new Date('2023-01-10T00:00:00.000Z')
276
276
  };
277
- const href = 'fake href';
278
-
279
- const journey = {
280
- getCurrentQuestionUrl: () => {
281
- return href;
282
- }
283
- };
284
277
 
285
- const result = dateQuestion.formatAnswerForSummary('segment', journey, answer);
278
+ const result = dateQuestion.formatAnswer(answer);
286
279
 
287
- assert.strictEqual(result[0].value, 'Start: 00:00 1 January 2023<br>End: 00:00 10 January 2023');
288
- assert.strictEqual(result[0].action.href, href);
289
- assert.strictEqual(result[0].action.text, 'Change');
290
- assert.strictEqual(result[0].action.visuallyHiddenText, QUESTION);
291
- assert.strictEqual(result[0].key, TITLE);
280
+ assert.strictEqual(result, 'Start: 00:00 1 January 2023<br>End: 00:00 10 January 2023');
292
281
  });
282
+
293
283
  it('should return start only if set', () => {
294
284
  const dateQuestion = new DatePeriodQuestion({
295
285
  title: TITLE,
@@ -304,21 +294,30 @@ describe('DatePeriodQuestion', () => {
304
294
  const answer = {
305
295
  start: new Date('2023-01-01T00:00:00.000Z')
306
296
  };
307
- const href = 'fake href';
308
297
 
309
- const journey = {
310
- getCurrentQuestionUrl: () => {
311
- return href;
312
- }
298
+ const result = dateQuestion.formatAnswer(answer);
299
+
300
+ assert.strictEqual(result, 'Start: 00:00 1 January 2023');
301
+ });
302
+
303
+ it('should return end only if set', () => {
304
+ const dateQuestion = new DatePeriodQuestion({
305
+ title: TITLE,
306
+ question: QUESTION,
307
+ fieldName: FIELDNAME,
308
+ hint: HINT,
309
+ hintStart: HINTSTART,
310
+ hintEnd: HINTEND,
311
+ validators: VALIDATORS
312
+ });
313
+
314
+ const answer = {
315
+ end: new Date('2023-01-10T00:00:00.000Z')
313
316
  };
314
317
 
315
- const result = dateQuestion.formatAnswerForSummary('segment', journey, answer);
318
+ const result = dateQuestion.formatAnswer(answer);
316
319
 
317
- assert.strictEqual(result[0].value, 'Start: 00:00 1 January 2023');
318
- assert.strictEqual(result[0].action.href, href);
319
- assert.strictEqual(result[0].action.text, 'Change');
320
- assert.strictEqual(result[0].action.visuallyHiddenText, QUESTION);
321
- assert.strictEqual(result[0].key, TITLE);
320
+ assert.strictEqual(result, 'End: 00:00 10 January 2023');
322
321
  });
323
322
 
324
323
  it('should use custom labels if set', () => {
@@ -333,6 +332,66 @@ describe('DatePeriodQuestion', () => {
333
332
  labels: { start: 'Open', end: 'Close' }
334
333
  });
335
334
 
335
+ const answer = {
336
+ start: new Date('2023-01-01T00:00:00.000Z'),
337
+ end: new Date('2023-01-10T00:00:00.000Z')
338
+ };
339
+
340
+ const result = dateQuestion.formatAnswer(answer);
341
+
342
+ assert.strictEqual(result, 'Open: 00:00 1 January 2023<br>Close: 00:00 10 January 2023');
343
+ });
344
+
345
+ it('should return not started text if answer does not exist', () => {
346
+ const dateQuestion = new DatePeriodQuestion({
347
+ title: TITLE,
348
+ question: QUESTION,
349
+ fieldName: FIELDNAME,
350
+ hint: HINT,
351
+ hintStart: HINTSTART,
352
+ hintEnd: HINTEND,
353
+ validators: VALIDATORS
354
+ });
355
+
356
+ const result = dateQuestion.formatAnswer(null);
357
+
358
+ assert.strictEqual(result, dateQuestion.notStartedText);
359
+ });
360
+
361
+ it('should escape html in labels', () => {
362
+ const dateQuestion = new DatePeriodQuestion({
363
+ title: TITLE,
364
+ question: QUESTION,
365
+ fieldName: FIELDNAME,
366
+ hint: HINT,
367
+ hintStart: HINTSTART,
368
+ hintEnd: HINTEND,
369
+ validators: VALIDATORS,
370
+ labels: { start: '<b>Start</b>', end: 'End' }
371
+ });
372
+
373
+ const answer = {
374
+ start: new Date('2023-01-01T00:00:00.000Z')
375
+ };
376
+
377
+ const result = dateQuestion.formatAnswer(answer);
378
+
379
+ assert.strictEqual(result, '&lt;b&gt;Start&lt;/b&gt;: 00:00 1 January 2023');
380
+ });
381
+ });
382
+
383
+ describe('formatAnswerForSummary', () => {
384
+ it('should integrate formatAnswer output with the summary row action and key', () => {
385
+ const dateQuestion = new DatePeriodQuestion({
386
+ title: TITLE,
387
+ question: QUESTION,
388
+ fieldName: FIELDNAME,
389
+ hint: HINT,
390
+ hintStart: HINTSTART,
391
+ hintEnd: HINTEND,
392
+ validators: VALIDATORS
393
+ });
394
+
336
395
  const answer = {
337
396
  start: new Date('2023-01-01T00:00:00.000Z'),
338
397
  end: new Date('2023-01-10T00:00:00.000Z')
@@ -347,14 +406,15 @@ describe('DatePeriodQuestion', () => {
347
406
 
348
407
  const result = dateQuestion.formatAnswerForSummary('segment', journey, answer);
349
408
 
350
- assert.strictEqual(result[0].value, 'Open: 00:00 1 January 2023<br>Close: 00:00 10 January 2023');
409
+ assert.strictEqual(result[0].value, dateQuestion.formatAnswer(answer));
410
+ assert.strictEqual(result[0].value, 'Start: 00:00 1 January 2023<br>End: 00:00 10 January 2023');
351
411
  assert.strictEqual(result[0].action.href, href);
352
412
  assert.strictEqual(result[0].action.text, 'Change');
353
413
  assert.strictEqual(result[0].action.visuallyHiddenText, QUESTION);
354
414
  assert.strictEqual(result[0].key, TITLE);
355
415
  });
356
416
 
357
- it('should return not started if answer does not exist', () => {
417
+ it('should return not started action if answer does not exist', () => {
358
418
  const dateQuestion = new DatePeriodQuestion({
359
419
  title: TITLE,
360
420
  question: QUESTION,
@@ -17,13 +17,9 @@ export class ManageListQuestion extends Question {
17
17
  };
18
18
  }>;
19
19
  /**
20
- * returns the formatted answers values to be used to build task list elements
20
+ * Format the answer for display in the summary, either as a count or as a list of answers
21
21
  */
22
- formatAnswerForSummary(sectionSegment: any, journey: any, answer: any): {
23
- key: string;
24
- value: string;
25
- action: import("#typedefs/question-types.d.ts").ActionView | import("#typedefs/question-types.d.ts").ActionView[] | undefined;
26
- }[];
22
+ formatAnswer(answer: any): any;
27
23
  renderConfirmationAction(res: any, itemToRemove: any, viewModel: any): void;
28
24
  set section(section: import("../../section.js").Section);
29
25
  get section(): import("../../section.js").Section;
@@ -1 +1 @@
1
- {"version":3,"file":"question.d.ts","sourceRoot":"","sources":["question.js"],"names":[],"mappings":"AAKA;;;;;;GAMG;AAEH;IAOC;;OAEG;IACH,oBAFW,OAAO,+BAA+B,EAAE,wBAAwB,EAe1E;IAcD,wCAEC;IAyDD;;;;OAMC;IAED;;OAEG;IACH;;;;QAsBC;IAED,4EAQC;IAoCD,yDAEC;IATD,kDAKC;;CAKD;;;;;;mBAxLa,MAAM;;;;;;;;;;;;;;yBAPK,WAAW"}
1
+ {"version":3,"file":"question.d.ts","sourceRoot":"","sources":["question.js"],"names":[],"mappings":"AAKA;;;;;;GAMG;AAEH;IAOC;;OAEG;IACH,oBAFW,OAAO,+BAA+B,EAAE,wBAAwB,EAe1E;IAcD,wCAEC;IAyDD;;;;OAMC;IAED;;OAEG;IACH,+BAkBC;IAED,4EAQC;IAoCD,yDAEC;IATD,kDAKC;;CAKD;;;;;;mBApLa,MAAM;;;;;;;;;;;;;;yBAPK,WAAW"}
@@ -116,30 +116,26 @@ export class ManageListQuestion extends Question {
116
116
  }
117
117
 
118
118
  /**
119
- * returns the formatted answers values to be used to build task list elements
119
+ * Format the answer for display in the summary, either as a count or as a list of answers
120
120
  */
121
- formatAnswerForSummary(sectionSegment, journey, answer) {
122
- let formattedAnswer = this.notStartedText;
123
- if (answer && Array.isArray(answer)) {
124
- if (this.#showAnswersInSummary) {
125
- const answers = answer.map((a) => this.#formatItemAnswers(a));
126
- // note: nunjucks.render uses the last configured environment
127
- // so we assume here that it is the one used by the main application and
128
- // is configured for dynamic-forms and govuk components
129
- formattedAnswer = nunjucks.render('components/manage-list/answer-summary-list.njk', { answers });
130
- } else if (answer.length > 0) {
131
- formattedAnswer = `${answer.length} ${this.title}`;
132
- }
121
+ formatAnswer(answer) {
122
+ if (!answer || !Array.isArray(answer)) {
123
+ return this.notStartedText;
133
124
  }
134
- const action = this.getAction(sectionSegment, journey, answer);
135
- const key = this.title ?? this.question;
136
- return [
137
- {
138
- key: key,
139
- value: formattedAnswer,
140
- action: action
141
- }
142
- ];
125
+
126
+ if (this.#showAnswersInSummary) {
127
+ const answers = answer.map((a) => this.#formatItemAnswers(a));
128
+ // note: nunjucks.render uses the last configured environment
129
+ // so we assume here that it is the one used by the main application and
130
+ // is configured for dynamic-forms and govuk components
131
+ return nunjucks.render('components/manage-list/answer-summary-list.njk', { answers });
132
+ }
133
+
134
+ if (answer.length > 0) {
135
+ return `${answer.length} ${this.title}`;
136
+ }
137
+
138
+ return this.notStartedText;
143
139
  }
144
140
 
145
141
  renderConfirmationAction(res, itemToRemove, viewModel) {
@@ -81,21 +81,45 @@ describe('components/manage-list/question', () => {
81
81
  });
82
82
  });
83
83
 
84
- it('should format list answer for summary', (ctx) => {
84
+ describe('formatAnswer', () => {
85
+ it('should return the not started text when answer is not set', () => {
86
+ const q = newQuestion();
87
+ assert.strictEqual(q.formatAnswer(undefined), q.notStartedText);
88
+ });
89
+
90
+ it('should return the not started text when answer is not an array', () => {
91
+ const q = newQuestion();
92
+ assert.strictEqual(q.formatAnswer('not-an-array'), q.notStartedText);
93
+ });
94
+
95
+ it('should return the not started text when answer is an empty array', () => {
96
+ const q = newQuestion();
97
+ assert.strictEqual(q.formatAnswer([]), q.notStartedText);
98
+ });
99
+
100
+ it('should return a count of the answers by default', () => {
101
+ const q = newQuestion();
102
+ assert.strictEqual(q.formatAnswer([{}, {}, {}]), '3 Things');
103
+ });
104
+
105
+ it('should render all answers when showAnswersInSummary is true', (ctx) => {
106
+ // nunjucks.render uses the last environment configured, so make sure one is configured
107
+ configureNunjucksTestEnv();
108
+ const { q } = questionWithManageQuestions(ctx, { showAnswersInSummary: true });
109
+ const formatted = q.formatAnswer([{}, {}, {}]);
110
+ assertSnapshot(ctx, formatted, 'manage-list-answer-summary.html');
111
+ });
112
+ });
113
+
114
+ it('should integrate with formatAnswerForSummary to build a full summary row', (ctx) => {
85
115
  const q = newQuestion();
86
116
  mockRandomUUID(ctx);
87
- const answerForSummary = q.formatAnswerForSummary('section-1', mockJourney(), [{}, {}, {}]);
117
+ const journey = mockJourney();
118
+ const answerForSummary = q.formatAnswerForSummary('section-1', journey, [{}, {}, {}]);
88
119
  assert.strictEqual(answerForSummary.length, 1);
120
+ assert.deepStrictEqual(answerForSummary[0].key, TITLE);
89
121
  assert.strictEqual(answerForSummary[0].value, '3 Things');
90
- });
91
-
92
- it('should support showing all answers in the format list answer for summary', (ctx) => {
93
- // nunjucks.render uses the last environment configured, so make sure one is configured
94
- configureNunjucksTestEnv();
95
- const { q } = questionWithManageQuestions(ctx, { showAnswersInSummary: true });
96
- const answerForSummary = q.formatAnswerForSummary('section-1', mockJourney(), [{}, {}, {}]);
97
- assert.strictEqual(answerForSummary.length, 1);
98
- assertSnapshot(ctx, answerForSummary[0].value, 'manage-list-answer-summary.html');
122
+ assert.ok(answerForSummary[0].action);
99
123
  });
100
124
 
101
125
  it('should render with answers', (ctx) => {
@@ -105,7 +105,7 @@ export class Question {
105
105
  *
106
106
  * @param {Object} options
107
107
  * @param {import('#typedefs/journey-types.d.ts').RouteParams} options.params
108
- * @param {import('../components/manage-list/question.js')} [options.manageListQuestion]
108
+ * @param {import('../components/manage-list/question.js').ManageListQuestion} [options.manageListQuestion]
109
109
  * @param {import('../section.js').Section} options.section - the current section
110
110
  * @param {import('../journey/journey.js').Journey} options.journey - the journey we are in
111
111
  * @param {Record<string, unknown>} [options.customViewData] additional data to send to view
@@ -114,7 +114,7 @@ export class Question {
114
114
  */
115
115
  toViewModel({ params, manageListQuestion, section, journey, customViewData, payload }: {
116
116
  params: import("#typedefs/journey-types.d.ts").RouteParams;
117
- manageListQuestion?: typeof import("../components/manage-list/question.js") | undefined;
117
+ manageListQuestion?: import("../components/manage-list/question.js").ManageListQuestion | undefined;
118
118
  section: import("../section.js").Section;
119
119
  journey: import("../journey/journey.js").Journey;
120
120
  customViewData?: Record<string, unknown> | undefined;
@@ -167,10 +167,10 @@ export class Question {
167
167
  * @param {import('express').Request} req
168
168
  * @param {import('../journey/journey.js').Journey} journey
169
169
  * @param {import('../section.js').Section} section
170
- * @param {import('../components/manage-list/question.js')} [manageListQuestion]
170
+ * @param {import('../components/manage-list/question.js').ManageListQuestion} [manageListQuestion]
171
171
  * @returns {import('#typedefs/question-types.d.ts').QuestionViewModel|undefined} returns the view model for displaying the error or undefined if there are no errors
172
172
  */
173
- checkForValidationErrors(req: import("express").Request, section: import("../section.js").Section, journey: import("../journey/journey.js").Journey, manageListQuestion?: typeof import("../components/manage-list/question.js")): import("#typedefs/question-types.d.ts").QuestionViewModel | undefined;
173
+ checkForValidationErrors(req: import("express").Request, section: import("../section.js").Section, journey: import("../journey/journey.js").Journey, manageListQuestion?: import("../components/manage-list/question.js").ManageListQuestion): import("#typedefs/question-types.d.ts").QuestionViewModel | undefined;
174
174
  /**
175
175
  * Get the data to save from the request, returns an object of answers
176
176
  *
@@ -1 +1 @@
1
- {"version":3,"file":"question.d.ts","sourceRoot":"","sources":["question.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"question.d.ts","sourceRoot":"","sources":["question.js"],"names":[],"mappings":"AAKA;;;GAGG;AACH;IAiEC;;;OAGG;IACH,+NAHW,OAAO,+BAA+B,EAAE,kBAAkB,oBAC1D,MAAM,CAAC,MAAM,WAAW,EA0DlC;IA5HD,6EAA6E;IAC7E,WADW,MAAM,CACP;IACV,sDAAsD;IACtD,OADW,MAAM,CACX;IACN,+DAA+D;IAC/D,UADW,MAAM,CACR;IACT,mFAAmF;IACnF,aADW,MAAM,GAAC,SAAS,CACf;IACZ,iDAAiD;IACjD,YADW,MAAM,CACN;IACX,qHAAqH;IACrH,WADW,MAAM,CACP;IACV,6FAA6F;IAC7F,UADW,OAAO,CACF;IAChB,0IAA0I;IAC1I,YADW,KAAK,CAAE,OAAO,gCAAgC,EAAE,aAAa,CAAC,CACzD;IAChB,2DAA2D;IAC3D,MADW,MAAM,GAAC,SAAS,CACtB;IACL,sEAAsE;IACtE,oBADW,OAAO,CACQ;IAC1B,oDAAoD;IACpD,KADW,MAAM,GAAC,SAAS,CACvB;IACJ,qDAAqD;IACrD,MADW,MAAM,GAAC,SAAS,CACtB;IACL,sDAAsD;IACtD,eADW,MAAM,GAAC,SAAS,CACb;IACd,gGAAgG;IAChG,YADW,OAAO,+BAA+B,EAAE,UAAU,GAAC,SAAS,CAC5D;IAEX,iFAAiF;IACjF,gBADW,MAAM,CACc;IAC/B,sFAAsF;IACtF,kBADW,OAAO,CACM;IACxB,4CAA4C;IAC5C,oBADW,MAAM,CACe;IAChC,uDAAuD;IACvD,kBADW,MAAM,CACW;IAC5B,uDAAuD;IACvD,kBADW,MAAM,CACW;IAC5B,oDAAoD;IACpD,eADW,MAAM,CACK;IACtB,0IAA0I;IAC1I,oBADW,OAAO,+BAA+B,EAAE,qBAAqB,GAAC,SAAS,CAC/D;IAEnB;;;OAGG;IAEH,gBAAiB,WAJN,OAAO,gCAAgC,EAAE,eAI3B,KAHZ,OAAO,CAGe;IAEnC;;;MAGE;IACF;;;;;;OAMG;IACH,wBAFU,OAAO,CAEc;IA2C9B,iCAAgC;IAChC,kBAAwB;IAExB;;;;MAAwB;IAkBzB;;;;;;OAMG;IACH,4BAFa,OAAO,CAInB;IAWD,iCANa,OAAO,EAWnB;IAdD;;;;OAIG;IACH,6BAFa,OAAO,CAInB;IAqBD;;;;;;OAMG;IACH,sBAFa,MAAM,EAAE,CAIpB;IAED;;;;;;;;;;;;;;OAcG;IACH,uFARG;QAAoE,MAAM,EAAlE,OAAO,8BAA8B,EAAE,WAAW;QAC2B,kBAAkB;QACtD,OAAO,EAAhD,OAAO,eAAe,EAAE,OAAO;QACkB,OAAO,EAAxD,OAAO,uBAAuB,EAAE,OAAO;QACL,cAAc;QAC9B,OAAO,GAAzB,OAAO;KACf,GAAU,OAAO,+BAA+B,EAAE,iBAAiB,CASrE;IAED;;;;;;;;;OASG;IACH,kCAPW,OAAO,eAAe,EAAE,OAAO,WAC/B,OAAO,uBAAuB,EAAE,OAAO,mBACvC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YACvB,OAAO,YACP,OAAO,+BAA+B,EAAE,+BAA+B,GACrE,OAAO,+BAA+B,EAAE,iBAAiB,CAuCrE;IAED;;;;;;;;OAQG,CACH,4BAJW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,uBAEjB,GAAC,GAAC,MAAM,CAIpB;IAED;;;;;;OAMG,CACH,oCAFW,OAAO,+BAA+B,EAAE,iBAAiB,QAE9B;IAEtC;;;;;;OAMG;IACH,0CAJW,OAAO,gCAAgC,EAAE,eAAe,mCACxD,OAAO,+BAA+B,EAAE,+BAA+B,GACrE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAc/B;IAED;;;;;OAKG;IACH,kBAJW,OAAO,SAAS,EAAE,QAAQ,aAC1B,OAAO,+BAA+B,EAAE,iBAAiB,GACvD,IAAI,CAShB;IAED;;;;;;;OAOG;IACH,8BANW,OAAO,SAAS,EAAE,OAAO,WAEzB,OAAO,eAAe,EAAE,OAAO,WAD/B,OAAO,uBAAuB,EAAE,OAAO,uBAEvC,OAAO,uCAAuC,EAAE,kBAAkB,GAChE,OAAO,+BAA+B,EAAE,iBAAiB,GAAC,SAAS,CAmB/E;IAED;;;;;;OAMG,CACH,mBAJW,OAAO,SAAS,EAAE,OAAO,mBACzB,OAAO,gCAAgC,EAAE,eAAe,GACtD,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAczD;IAED;;;;;;OAMG,CACH,0BALW,OAAO,SAAS,EAAE,OAAO,cAEzB,OAAO,eAAe,EAAE,OAAO,WAD/B,OAAO,uBAAuB,EAAE,OAAO,GAErC,OAAO,+BAA+B,EAAE,iBAAiB,GAAG,SAAS,CAIjF;IAED;;;;;;;;;OASG;IACH,wBAPW,OAAO,SAAS,EAAE,QAAQ,WAC1B,OAAO,uBAAuB,EAAE,OAAO,kBACvC,MAAM,mBACN,MAAM,GACJ,IAAI,CAQhB;IAED;;;;;;;OAOG;IACH,uCANW,MAAM,WACN,OAAO,uBAAuB,EAAE,OAAO,UACvC,OAAO,aACP,OAAO,GACL,OAAO,+BAA+B,EAAE,UAAU,EAAE,CA+BhE;IAED;;;;;;OAMG;IACH,0BALW,MAAM,WACN,OAAO,uBAAuB,EAAE,OAAO,UACvC,OAAO,GACL,OAAO,+BAA+B,EAAE,UAAU,GAAG,OAAO,+BAA+B,EAAE,UAAU,EAAE,GAAG,SAAS,CAqBjI;IAED;;;OAGG;IACH,eAHW,OAAO,GACL,OAAO,CAInB;IAED;;;;;;;OAOG;IACH,qBAHW,OAAO,GACL,MAAM,CAQlB;IAED;;OAEG;IACH,cAFa,OAAO,CAInB;IACD;;;OAGG;IACH,4BAHW,MAAM,GACJ,OAAO,CAMnB;IAED;;;;OAIG;IACH,4BAJW,OAAO,gCAAgC,EAAE,eAAe,cACxD,MAAM,GACJ,OAAO,CAInB;;CACD"}
@@ -192,7 +192,7 @@ export class Question {
192
192
  *
193
193
  * @param {Object} options
194
194
  * @param {import('#typedefs/journey-types.d.ts').RouteParams} options.params
195
- * @param {import('../components/manage-list/question.js')} [options.manageListQuestion]
195
+ * @param {import('../components/manage-list/question.js').ManageListQuestion} [options.manageListQuestion]
196
196
  * @param {import('../section.js').Section} options.section - the current section
197
197
  * @param {import('../journey/journey.js').Journey} options.journey - the journey we are in
198
198
  * @param {Record<string, unknown>} [options.customViewData] additional data to send to view
@@ -320,7 +320,7 @@ export class Question {
320
320
  * @param {import('express').Request} req
321
321
  * @param {import('../journey/journey.js').Journey} journey
322
322
  * @param {import('../section.js').Section} section
323
- * @param {import('../components/manage-list/question.js')} [manageListQuestion]
323
+ * @param {import('../components/manage-list/question.js').ManageListQuestion} [manageListQuestion]
324
324
  * @returns {import('#typedefs/question-types.d.ts').QuestionViewModel|undefined} returns the view model for displaying the error or undefined if there are no errors
325
325
  */
326
326
  checkForValidationErrors(req, section, journey, manageListQuestion) {
@@ -1,6 +1,3 @@
1
- /**
2
- * @typedef {import('../questions/question.js')} Question
3
- */
4
1
  /**
5
2
  * enforces a field is not empty when condition is satisfied
6
3
  * @class
@@ -20,6 +17,5 @@ export class ConditionalRequiredValidator extends BaseValidator {
20
17
  isValueIncluded(questionObj: any, value: any): import("express-validator").ValidationChain;
21
18
  }
22
19
  export default ConditionalRequiredValidator;
23
- export type Question = typeof import("../questions/question.js");
24
20
  import BaseValidator from './base-validator.js';
25
21
  //# sourceMappingURL=conditional-required-validator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conditional-required-validator.d.ts","sourceRoot":"","sources":["conditional-required-validator.js"],"names":[],"mappings":"AAKA;;GAEG;AAEH;;;GAGG;AACH;IAMC;;;OAGG;IACH,2BAFW,MAAM,EAQhB;IAED;;;OAGG;IACH,sBAFW,OAAO,kCAAkC,EAAE,eAAe,WAcpE;IAED,+DAEC;IAED,2FAKC;CACD;;;0BAzDyB,qBAAqB"}
1
+ {"version":3,"file":"conditional-required-validator.d.ts","sourceRoot":"","sources":["conditional-required-validator.js"],"names":[],"mappings":"AAIA;;;GAGG;AACH;IAMC;;;OAGG;IACH,2BAFW,MAAM,EAQhB;IAED;;;OAGG;IACH,sBAFW,OAAO,kCAAkC,EAAE,eAAe,WAcpE;IAED,+DAEC;IAED,2FAKC;CACD;;0BArDyB,qBAAqB"}
@@ -1,12 +1,7 @@
1
1
  import { body } from 'express-validator';
2
-
3
2
  import BaseValidator from './base-validator.js';
4
3
  import { toArray } from '#src/lib/utils.js';
5
4
 
6
- /**
7
- * @typedef {import('../questions/question.js')} Question
8
- */
9
-
10
5
  /**
11
6
  * enforces a field is not empty when condition is satisfied
12
7
  * @class
@@ -1,6 +1,3 @@
1
- /**
2
- * @typedef {import('../questions/question.js')} Question
3
- */
4
1
  /**
5
2
  * enforces a confirmation checkbox is checked before proceeding
6
3
  * @class
@@ -23,6 +20,5 @@ export class ConfirmationCheckboxValidator extends BaseValidator {
23
20
  validate(): import("express-validator").ValidationChain;
24
21
  }
25
22
  export default ConfirmationCheckboxValidator;
26
- export type Question = typeof import("../questions/question.js");
27
23
  import BaseValidator from './base-validator.js';
28
24
  //# sourceMappingURL=confirmation-checkbox-validator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"confirmation-checkbox-validator.d.ts","sourceRoot":"","sources":["confirmation-checkbox-validator.js"],"names":[],"mappings":"AAIA;;GAEG;AAEH;;;GAGG;AACH;IAMC;;;;;OAKG;IACH,4CAHG;QAAuB,YAAY,EAA3B,MAAM;QACS,YAAY,EAA3B,MAAM;KAChB,EAMA;IAFA,qBAAgC;IAIjC;;OAEG;IACH,wDAEC;CACD;;;0BAnCyB,qBAAqB"}
1
+ {"version":3,"file":"confirmation-checkbox-validator.d.ts","sourceRoot":"","sources":["confirmation-checkbox-validator.js"],"names":[],"mappings":"AAGA;;;GAGG;AACH;IAMC;;;;;OAKG;IACH,4CAHG;QAAuB,YAAY,EAA3B,MAAM;QACS,YAAY,EAA3B,MAAM;KAChB,EAMA;IAFA,qBAAgC;IAIjC;;OAEG;IACH,wDAEC;CACD;;0BA/ByB,qBAAqB"}
@@ -1,11 +1,6 @@
1
1
  import { body } from 'express-validator';
2
-
3
2
  import BaseValidator from './base-validator.js';
4
3
 
5
- /**
6
- * @typedef {import('../questions/question.js')} Question
7
- */
8
-
9
4
  /**
10
5
  * enforces a confirmation checkbox is checked before proceeding
11
6
  * @class
@@ -31,7 +31,7 @@ describe('question pages', () => {
31
31
  * @param {import('node:test').TestContext} ctx
32
32
  * @param {string} url
33
33
  * @param {string} snapshotName
34
- * @param {import('#src/questions/question.js')} q
34
+ * @param {import('#src/questions/question.js').Question} q
35
35
  * @returns {Promise<void>}
36
36
  */
37
37
  async function renderQuestionAndSnapshot(ctx, url, snapshotName, q) {
@@ -59,7 +59,7 @@ describe('question pages', () => {
59
59
  /**
60
60
  * @param {import('node:test').TestContext} ctx
61
61
  * @param {string} url
62
- * @param {import('#src/questions/question.js')} q
62
+ * @param {import('#src/questions/question.js').Question} q
63
63
  * @returns {Promise<string>}
64
64
  */
65
65
  async function postQuestionCheck(ctx, url, q) {