@oneblink/apps-react 6.11.0-beta.1 → 6.11.0-beta.10

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 (41) hide show
  1. package/dist/OneBlinkFormBase.js +4 -3
  2. package/dist/OneBlinkFormBase.js.map +1 -1
  3. package/dist/components/renderer/LookupButton.js +1 -1
  4. package/dist/components/renderer/LookupButton.js.map +1 -1
  5. package/dist/components/renderer/attachments/FileCard.js +1 -1
  6. package/dist/components/renderer/attachments/FileCard.js.map +1 -1
  7. package/dist/form-elements/FormElementCaptcha.d.ts +1 -1
  8. package/dist/form-elements/FormElementCaptcha.js +9 -5
  9. package/dist/form-elements/FormElementCaptcha.js.map +1 -1
  10. package/dist/form-elements/FormElementFiles.js +1 -1
  11. package/dist/form-elements/FormElementFiles.js.map +1 -1
  12. package/dist/form-elements/FormElementSection.js +1 -1
  13. package/dist/form-elements/FormElementSection.js.map +1 -1
  14. package/dist/form-elements/OptionButton.js +10 -2
  15. package/dist/form-elements/OptionButton.js.map +1 -1
  16. package/dist/hooks/useFormValidation.d.ts +1 -1
  17. package/dist/hooks/useFormValidation.js +10 -6
  18. package/dist/hooks/useFormValidation.js.map +1 -1
  19. package/dist/hooks/usePages.js +1 -1
  20. package/dist/hooks/usePages.js.map +1 -1
  21. package/dist/services/form-validation/extensions.d.ts +28 -0
  22. package/dist/services/form-validation/extensions.js +97 -0
  23. package/dist/services/form-validation/extensions.js.map +1 -0
  24. package/dist/services/form-validation/validate-dot-js.d.ts +63 -0
  25. package/dist/services/form-validation/validate-dot-js.js +328 -0
  26. package/dist/services/form-validation/validate-dot-js.js.map +1 -0
  27. package/dist/services/form-validation/validateSubmission.d.ts +11 -0
  28. package/dist/services/form-validation/validateSubmission.js +503 -0
  29. package/dist/services/form-validation/validateSubmission.js.map +1 -0
  30. package/dist/services/form-validation/validators.d.ts +13 -0
  31. package/dist/services/form-validation/validators.js +70 -0
  32. package/dist/services/form-validation/validators.js.map +1 -0
  33. package/dist/services/generateCivicaNameRecordElements.d.ts +1 -1
  34. package/dist/services/generateCivicaNameRecordElements.js.map +1 -1
  35. package/dist/styles/option-buttons.scss +5 -0
  36. package/dist/styles.css +6 -0
  37. package/dist/styles.scss +1 -0
  38. package/package.json +3 -3
  39. package/dist/services/form-validation.d.ts +0 -10
  40. package/dist/services/form-validation.js +0 -604
  41. package/dist/services/form-validation.js.map +0 -1
@@ -1,604 +0,0 @@
1
- import validate from 'validate.js';
2
- import { localisationService } from '@oneblink/apps';
3
- import { parseDateValue } from './generate-default-data';
4
- import generateCivicaNameRecordElements from './generateCivicaNameRecordElements';
5
- import generateFreshdeskDependentFieldElements from './generateFreshdeskDependentFieldElements';
6
- import cleanFormSubmissionModel from './cleanFormSubmissionModel';
7
- import getDateRangeConfiguration from './getDateRangeConfiguration';
8
- import getRepeatableSetEntriesConfiguration from './getRepeatableSetEntriesConfiguration';
9
- export const generateLookupValidationMessage = (lookupButtonConfig) => {
10
- return lookupButtonConfig && lookupButtonConfig.label
11
- ? `${lookupButtonConfig.label} is required`
12
- : 'Lookup is required';
13
- };
14
- // https://validatejs.org/#validators-datetime
15
- // Before using it we must add the parse and format functions
16
- // Here is a sample implementation using moment.js
17
- validate.extend(validate.validators.datetime, {
18
- // The value is guaranteed not to be null or undefined but otherwise it
19
- // could be anything.
20
- parse: function (value) {
21
- return Date.parse(value);
22
- },
23
- // Input is a unix timestamp
24
- format: function (value, options) {
25
- const dateValue = new Date(value);
26
- return options.format(dateValue);
27
- },
28
- });
29
- validate.validators.entries = function (value, { setSchema, entrySchema: { schema: entrySchema, formElementConditionallyShown, executedLookups, captchaType, }, }) {
30
- const entries = Array.isArray(value) ? value : [];
31
- const entryErrors = entries.reduce((errorsByIndex, entry, index) => {
32
- const entryValidation = validateSubmission(entrySchema, entry, (formElementConditionallyShown === null || formElementConditionallyShown === void 0 ? void 0 : formElementConditionallyShown.type) === 'repeatableSet'
33
- ? formElementConditionallyShown.entries[index.toString()]
34
- : undefined, Array.isArray(executedLookups) ? executedLookups[index] : {}, captchaType);
35
- if (entryValidation) {
36
- errorsByIndex[index] = entryValidation;
37
- }
38
- return errorsByIndex;
39
- }, {});
40
- const setErrorMessages = validate.single(value, setSchema);
41
- if (!setErrorMessages && validate.isEmpty(entryErrors)) {
42
- return;
43
- }
44
- return {
45
- type: 'repeatableSet',
46
- set: setErrorMessages && setErrorMessages[0],
47
- entries: entryErrors,
48
- };
49
- };
50
- validate.validators.nestedElements = function (value, { schema, formElementConditionallyShown, executedLookups, captchaType, }) {
51
- const errors = validateSubmission(schema, value, (formElementConditionallyShown === null || formElementConditionallyShown === void 0 ? void 0 : formElementConditionallyShown.type) === 'formElements'
52
- ? formElementConditionallyShown.formElements
53
- : undefined, typeof executedLookups !== 'boolean' ? executedLookups : {}, captchaType);
54
- if (!errors) {
55
- return;
56
- }
57
- return {
58
- type: 'formElements',
59
- formElements: errors,
60
- };
61
- };
62
- function getInvalidAttachment(value) {
63
- if (value &&
64
- typeof value === 'object' &&
65
- value.type &&
66
- value.type === 'ERROR') {
67
- return value;
68
- }
69
- }
70
- function validateAttachments(value) {
71
- const invalidAttachmentNames = value === null || value === void 0 ? void 0 : value.reduce((invalidAttachmentNames, att) => {
72
- var _a;
73
- const attachmentName = (_a = getInvalidAttachment(att)) === null || _a === void 0 ? void 0 : _a.fileName;
74
- if (attachmentName) {
75
- invalidAttachmentNames.push(attachmentName);
76
- }
77
- return invalidAttachmentNames;
78
- }, []);
79
- if (invalidAttachmentNames === null || invalidAttachmentNames === void 0 ? void 0 : invalidAttachmentNames.length) {
80
- return `${invalidAttachmentNames.join(', ')} could not be uploaded.`;
81
- }
82
- }
83
- validate.validators.attachment = function (value) {
84
- var _a;
85
- return (_a = getInvalidAttachment(value)) === null || _a === void 0 ? void 0 : _a.errorMessage;
86
- };
87
- validate.validators.attachments = function (value) {
88
- if (Array.isArray(value)) {
89
- return validateAttachments(value);
90
- }
91
- return validateAttachments(value === null || value === void 0 ? void 0 : value.files);
92
- };
93
- // Extend validator for lookups
94
- validate.validators.lookups = function (value, { executedLookups, formElement, }) {
95
- if (!formElement.isDataLookup && !formElement.isElementLookup) {
96
- return;
97
- }
98
- // Lookups must only be executed on required form elements
99
- if (formElement && !formElement.required) {
100
- return;
101
- }
102
- const elementExecutedLookups = executedLookups === null || executedLookups === void 0 ? void 0 : executedLookups[formElement.name];
103
- if (elementExecutedLookups === true) {
104
- return;
105
- }
106
- return generateLookupValidationMessage(formElement.lookupButton);
107
- };
108
- validate.validators.numberRegex = function (value, format) {
109
- if (!format) {
110
- return;
111
- }
112
- if (typeof value === 'number' && !Number.isNaN(value)) {
113
- value = value.toString();
114
- }
115
- const errorMessages = validate.single(value, { format });
116
- return errorMessages && errorMessages[0];
117
- };
118
- validate.validators.isTrue = function (value, message) {
119
- if (!value) {
120
- return message || 'Must be set to true';
121
- }
122
- };
123
- validate.validators.needsExtension = function (value, formElement) {
124
- const isValid = !Array.isArray(value) ||
125
- value.every((file) => {
126
- return checkFileNameExtensionIsValid(formElement, file.fileName);
127
- });
128
- if (!isValid)
129
- return 'All files must have extensions';
130
- };
131
- function getCustomRegexFormatConfig(formElement) {
132
- return formElement.regexPattern
133
- ? {
134
- pattern: formElement.regexPattern,
135
- flags: formElement.regexFlags,
136
- message: formElement.regexMessage,
137
- }
138
- : undefined;
139
- }
140
- const presence = ({ required, requiredMessage }, message) => (required ? { message: requiredMessage || message } : false);
141
- const escapeElementName = (elementName) => {
142
- const escapedName = elementName.replace(/\./g, '\\.');
143
- return escapedName;
144
- };
145
- function getCleanDateRangeConfiguration(options, elements, submission, formElementsConditionallyShown) {
146
- if (options.referenceFormElementId && submission) {
147
- const { model } = cleanFormSubmissionModel(submission, elements, formElementsConditionallyShown, true);
148
- return getDateRangeConfiguration(options, elements, model);
149
- }
150
- return [options.date, options.daysOffset];
151
- }
152
- function getCleanRepeatableSetConfiguration(setEntries, elements, submission, formElementsConditionallyShown) {
153
- if (submission) {
154
- const { model } = cleanFormSubmissionModel(submission, elements, formElementsConditionallyShown, true);
155
- return getRepeatableSetEntriesConfiguration(setEntries, elements, model);
156
- }
157
- }
158
- export function generateValidationSchema(elements) {
159
- return elements.reduce((partialSchema, formElement) => {
160
- switch (formElement.type) {
161
- // Elements that do not need to be validated
162
- case 'summary':
163
- case 'calculation':
164
- case 'image':
165
- case 'html':
166
- case 'heading':
167
- case 'arcGISWebMap': {
168
- return partialSchema;
169
- }
170
- }
171
- const constraint = (value, submission, propertyName, { formElementsConditionallyShown, executedLookups, captchaType }) => {
172
- var _a, _b;
173
- // If the element is current hidden, we do not need to apply validation
174
- const formElementConditionallyShown = formElementsConditionallyShown === null || formElementsConditionallyShown === void 0 ? void 0 : formElementsConditionallyShown[formElement.name];
175
- if (formElementConditionallyShown === null || formElementConditionallyShown === void 0 ? void 0 : formElementConditionallyShown.isHidden) {
176
- return;
177
- }
178
- switch (formElement.type) {
179
- case 'draw': {
180
- return {
181
- attachment: true,
182
- presence: presence(formElement, 'A saved signature is required'),
183
- };
184
- }
185
- case 'camera': {
186
- return {
187
- attachment: true,
188
- presence: presence(formElement, 'A photo is required'),
189
- };
190
- }
191
- case 'captcha': {
192
- switch (captchaType) {
193
- case 'INVISIBLE':
194
- return;
195
- case 'CHECKBOX':
196
- default:
197
- return {
198
- presence: presence({ ...formElement, required: true }, 'Please complete the CAPTCHA successfully'),
199
- };
200
- }
201
- }
202
- case 'location': {
203
- return {
204
- presence: presence(formElement, 'Please select a location'),
205
- lookups: {
206
- formElement,
207
- executedLookups,
208
- },
209
- };
210
- }
211
- case 'compliance': {
212
- return {
213
- presence: presence(formElement, 'Required'),
214
- lookups: {
215
- formElement,
216
- executedLookups,
217
- },
218
- attachments: true,
219
- };
220
- }
221
- case 'checkboxes': {
222
- const optionsLength = (formElementConditionallyShown === null || formElementConditionallyShown === void 0 ? void 0 : formElementConditionallyShown.type) === 'formElement' &&
223
- (formElementConditionallyShown === null || formElementConditionallyShown === void 0 ? void 0 : formElementConditionallyShown.options)
224
- ? (_a = formElementConditionallyShown === null || formElementConditionallyShown === void 0 ? void 0 : formElementConditionallyShown.options) === null || _a === void 0 ? void 0 : _a.length
225
- : (_b = formElement.options) === null || _b === void 0 ? void 0 : _b.length;
226
- const requiredAllDefaultMessage = 'All options are required';
227
- return {
228
- presence: presence({
229
- ...formElement,
230
- required: !!optionsLength &&
231
- (formElement.required || !!formElement.requiredAll),
232
- }, formElement.requiredAll ? requiredAllDefaultMessage : 'Required'),
233
- length: formElement.requiredAll
234
- ? {
235
- is: optionsLength,
236
- message: formElement.requiredMessage || requiredAllDefaultMessage,
237
- }
238
- : undefined,
239
- lookups: {
240
- formElement,
241
- executedLookups,
242
- },
243
- };
244
- }
245
- case 'abn':
246
- case 'geoscapeAddress':
247
- case 'pointAddress':
248
- case 'googleAddress':
249
- case 'civicaStreetName':
250
- case 'autocomplete':
251
- case 'radio':
252
- case 'select':
253
- case 'apiNSWLiquorLicence': {
254
- return {
255
- presence: presence(formElement, 'Required'),
256
- lookups: {
257
- formElement,
258
- executedLookups,
259
- },
260
- };
261
- }
262
- case 'boolean': {
263
- return {
264
- isTrue: formElement.required &&
265
- (formElement.requiredMessage || 'Required'),
266
- lookups: {
267
- formElement,
268
- executedLookups,
269
- },
270
- };
271
- }
272
- case 'bsb': {
273
- return {
274
- presence: presence(formElement, 'Please enter a BSB number'),
275
- format: {
276
- pattern: /\d{3}-\d{3}/,
277
- message: 'Please enter a valid BSB number',
278
- },
279
- lookups: {
280
- formElement,
281
- executedLookups,
282
- },
283
- };
284
- }
285
- case 'barcodeScanner': {
286
- return {
287
- presence: presence(formElement, 'Please scan a barcode or enter a value'),
288
- format: getCustomRegexFormatConfig(formElement),
289
- lookups: {
290
- formElement,
291
- executedLookups,
292
- },
293
- };
294
- }
295
- case 'text':
296
- case 'textarea': {
297
- return {
298
- presence: presence(formElement, 'Please enter a value'),
299
- length: {
300
- minimum: formElement.minLength,
301
- tooShort: 'Please enter a value with at least %{count} character(s)',
302
- maximum: formElement.maxLength,
303
- tooLong: 'Please enter a value with %{count} character(s) or less',
304
- },
305
- format: getCustomRegexFormatConfig(formElement),
306
- lookups: {
307
- formElement,
308
- executedLookups,
309
- },
310
- };
311
- }
312
- case 'telephone': {
313
- return {
314
- presence: presence(formElement, 'Please enter a phone number'),
315
- format: getCustomRegexFormatConfig(formElement),
316
- lookups: {
317
- formElement,
318
- executedLookups,
319
- },
320
- };
321
- }
322
- case 'email': {
323
- return {
324
- presence: presence(formElement, 'Please enter an email address'),
325
- email: {
326
- message: 'Please enter a valid email for this field',
327
- },
328
- format: getCustomRegexFormatConfig(formElement),
329
- lookups: {
330
- formElement,
331
- executedLookups,
332
- },
333
- };
334
- }
335
- case 'time': {
336
- return {
337
- presence: presence(formElement, 'Please select a time'),
338
- lookups: {
339
- formElement,
340
- executedLookups,
341
- },
342
- };
343
- }
344
- case 'date': {
345
- const [fromDate, fromDateDaysOffset] = getCleanDateRangeConfiguration({
346
- date: formElement.fromDate,
347
- daysOffset: formElement.fromDateDaysOffset,
348
- referenceFormElementId: formElement.fromDateElementId,
349
- }, elements, submission, formElementsConditionallyShown);
350
- const [toDate, toDateDaysOffset] = getCleanDateRangeConfiguration({
351
- date: formElement.toDate,
352
- daysOffset: formElement.toDateDaysOffset,
353
- referenceFormElementId: formElement.toDateElementId,
354
- }, elements, submission, formElementsConditionallyShown);
355
- return {
356
- presence: presence(formElement, 'Please select a date'),
357
- date: {
358
- format: (v) => localisationService.formatDate(v),
359
- earliest: parseDateValue({
360
- dateOnly: true,
361
- daysOffset: fromDateDaysOffset,
362
- value: fromDate,
363
- }),
364
- latest: parseDateValue({
365
- dateOnly: true,
366
- daysOffset: toDateDaysOffset,
367
- value: toDate,
368
- }),
369
- notValid: 'Please select a valid date',
370
- tooEarly: 'Date cannot be before %{date}',
371
- tooLate: 'Date cannot be after %{date}',
372
- },
373
- lookups: {
374
- formElement,
375
- executedLookups,
376
- },
377
- };
378
- }
379
- case 'datetime': {
380
- const [fromDate, fromDateDaysOffset] = getCleanDateRangeConfiguration({
381
- date: formElement.fromDate,
382
- daysOffset: formElement.fromDateDaysOffset,
383
- referenceFormElementId: formElement.fromDateElementId,
384
- }, elements, submission, formElementsConditionallyShown);
385
- const [toDate, toDateDaysOffset] = getCleanDateRangeConfiguration({
386
- date: formElement.toDate,
387
- daysOffset: formElement.toDateDaysOffset,
388
- referenceFormElementId: formElement.toDateElementId,
389
- }, elements, submission, formElementsConditionallyShown);
390
- return {
391
- presence: presence(formElement, 'Please select a date and time'),
392
- datetime: {
393
- format: (v) => localisationService.formatDatetime(v),
394
- earliest: parseDateValue({
395
- dateOnly: false,
396
- daysOffset: fromDateDaysOffset,
397
- value: fromDate,
398
- }),
399
- latest: parseDateValue({
400
- dateOnly: false,
401
- daysOffset: toDateDaysOffset,
402
- value: toDate,
403
- }),
404
- notValid: 'Please select a valid date and time',
405
- tooEarly: 'Date and time cannot be before %{date}',
406
- tooLate: 'Date and time cannot be after %{date}',
407
- },
408
- lookups: {
409
- formElement,
410
- executedLookups,
411
- },
412
- };
413
- }
414
- case 'number': {
415
- let minErrorMessage = 'Please enter a number greater than or equal to %{count}';
416
- let maxErrorMessage = 'Please enter a number less than or equal to %{count}';
417
- if (typeof formElement.minNumber === 'number' &&
418
- typeof formElement.maxNumber === 'number') {
419
- minErrorMessage =
420
- maxErrorMessage = `Please enter a number between ${formElement.minNumber} and ${formElement.maxNumber}`;
421
- }
422
- return {
423
- type: 'number',
424
- presence: presence(formElement, 'Please enter a number'),
425
- numericality: {
426
- greaterThanOrEqualTo: formElement.minNumber,
427
- notGreaterThanOrEqualTo: minErrorMessage,
428
- lessThanOrEqualTo: formElement.maxNumber,
429
- notLessThanOrEqualTo: maxErrorMessage,
430
- onlyInteger: formElement.isInteger,
431
- notInteger: 'Please enter a whole number',
432
- },
433
- numberRegex: getCustomRegexFormatConfig(formElement),
434
- lookups: {
435
- formElement,
436
- executedLookups,
437
- },
438
- };
439
- }
440
- case 'files': {
441
- return {
442
- presence: formElement.minEntries
443
- ? {
444
- message: `Please upload at least ${formElement.minEntries} file${formElement.minEntries === 1 ? '' : 's'}`,
445
- }
446
- : false,
447
- length: {
448
- minimum: formElement.minEntries,
449
- maximum: formElement.maxEntries,
450
- tooLong: 'Cannot upload more than %{count} file(s)',
451
- tooShort: 'Please upload at least %{count} file(s)',
452
- },
453
- type: {
454
- type: (files) => {
455
- return (!Array.isArray(files) ||
456
- files.every((file) => {
457
- return checkFileNameIsValid(formElement, file.fileName);
458
- }));
459
- },
460
- message: `Only the following file types are accepted: ${(formElement.restrictedFileTypes || []).join(', ')}`,
461
- },
462
- needsExtension: formElement,
463
- attachments: true,
464
- };
465
- }
466
- case 'repeatableSet': {
467
- const minSetEntries = getCleanRepeatableSetConfiguration(formElement.minSetEntries, elements, submission, formElementsConditionallyShown);
468
- const maxSetEntries = getCleanRepeatableSetConfiguration(formElement.maxSetEntries, elements, submission, formElementsConditionallyShown);
469
- const repeatableSetExecutedLookups = executedLookups !== undefined &&
470
- typeof executedLookups !== 'boolean' &&
471
- !Array.isArray(executedLookups) &&
472
- Array.isArray(executedLookups[formElement.name])
473
- ? executedLookups[formElement.name]
474
- : [];
475
- return {
476
- entries: {
477
- setSchema: {
478
- presence: minSetEntries
479
- ? {
480
- message: `Must have at least ${minSetEntries} ${minSetEntries === 1 ? 'entry' : 'entries'}`,
481
- }
482
- : false,
483
- length: {
484
- minimum: minSetEntries,
485
- maximum: maxSetEntries,
486
- tooLong: 'Cannot have more than %{count} entry/entries',
487
- tooShort: 'Must have at least %{count} entry/entries',
488
- },
489
- },
490
- entrySchema: {
491
- schema: generateValidationSchema(formElement.elements),
492
- formElementConditionallyShown: formElementsConditionallyShown === null || formElementsConditionallyShown === void 0 ? void 0 : formElementsConditionallyShown[formElement.name],
493
- executedLookups: repeatableSetExecutedLookups,
494
- },
495
- },
496
- };
497
- }
498
- case 'civicaNameRecord': {
499
- const nestedElements = generateCivicaNameRecordElements(formElement, []);
500
- const nestedExecutedLookups = executedLookups !== undefined &&
501
- typeof executedLookups !== 'boolean' &&
502
- !Array.isArray(executedLookups)
503
- ? executedLookups[formElement.name]
504
- : {};
505
- return {
506
- nestedElements: {
507
- schema: generateValidationSchema(nestedElements),
508
- formElementConditionallyShown: formElementsConditionallyShown === null || formElementsConditionallyShown === void 0 ? void 0 : formElementsConditionallyShown[formElement.name],
509
- executedLookups: nestedExecutedLookups,
510
- },
511
- };
512
- }
513
- case 'infoPage':
514
- case 'form': {
515
- if (formElement.elements) {
516
- const nestedExecutedLookups = executedLookups !== undefined &&
517
- typeof executedLookups !== 'boolean' &&
518
- !Array.isArray(executedLookups)
519
- ? executedLookups[formElement.name]
520
- : {};
521
- return {
522
- nestedElements: {
523
- schema: generateValidationSchema(formElement.elements),
524
- formElementConditionallyShown: formElementsConditionallyShown === null || formElementsConditionallyShown === void 0 ? void 0 : formElementsConditionallyShown[formElement.name],
525
- executedLookups: nestedExecutedLookups,
526
- },
527
- };
528
- }
529
- break;
530
- }
531
- case 'freshdeskDependentField': {
532
- const nestedElements = generateFreshdeskDependentFieldElements(formElement);
533
- const nestedExecutedLookups = executedLookups !== undefined &&
534
- typeof executedLookups !== 'boolean' &&
535
- !Array.isArray(executedLookups)
536
- ? executedLookups[formElement.name]
537
- : {};
538
- return {
539
- nestedElements: {
540
- schema: generateValidationSchema(nestedElements),
541
- formElementConditionallyShown: formElementsConditionallyShown === null || formElementsConditionallyShown === void 0 ? void 0 : formElementsConditionallyShown[formElement.name],
542
- executedLookups: nestedExecutedLookups,
543
- },
544
- };
545
- }
546
- default: {
547
- console.info('Unsupported form element with validation', formElement);
548
- }
549
- }
550
- };
551
- partialSchema[escapeElementName(formElement.name)] = constraint;
552
- return partialSchema;
553
- }, {});
554
- }
555
- export function validateSubmission(schema, submission, formElementsConditionallyShown, executedLookups, captchaType) {
556
- const errorsAsArray = validate(submission, schema, {
557
- format: 'grouped',
558
- fullMessages: false,
559
- formElementsConditionallyShown,
560
- executedLookups,
561
- captchaType,
562
- });
563
- if (!errorsAsArray || validate.isEmpty(errorsAsArray)) {
564
- return;
565
- }
566
- const errors = Object.keys(errorsAsArray || {}).reduce((messagesByFormElementName, key) => {
567
- const validationMessage = errorsAsArray[key][0];
568
- if (validationMessage) {
569
- messagesByFormElementName[key.replace(/\\./g, '.')] = validationMessage;
570
- }
571
- return messagesByFormElementName;
572
- }, {});
573
- if (validate.isEmpty(errors)) {
574
- return;
575
- }
576
- return errors;
577
- }
578
- export function checkFileNameIsValid(formElement, fileName) {
579
- const extension = fileName.split('.').pop();
580
- return (!formElement.restrictedFileTypes ||
581
- formElement.restrictedFileTypes.some((fileType) => fileType.toLowerCase() === (extension === null || extension === void 0 ? void 0 : extension.toLowerCase())));
582
- }
583
- export function checkFileNameExtensionIsValid(formElement, fileName) {
584
- return (formElement.allowExtensionlessAttachments || fileName.split('.').length >= 2);
585
- }
586
- export function checkSectionValidity(element, formElementsValidation) {
587
- // If everything is valid, no need to check elements
588
- if (!formElementsValidation) {
589
- return false;
590
- }
591
- // If there is no elements on the page that are invalid, we will treat as valid
592
- return element.elements.some((formElement) => {
593
- switch (formElement.type) {
594
- case 'page':
595
- case 'section': {
596
- return checkSectionValidity(formElement, formElementsValidation);
597
- }
598
- default: {
599
- return formElementsValidation[formElement.name];
600
- }
601
- }
602
- });
603
- }
604
- //# sourceMappingURL=form-validation.js.map