@defra/fcp-sfd-frontend-engine 0.4.0 → 0.5.0
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/dist/index.cjs +143 -26
- package/dist/index.js +143 -26
- package/package.json +1 -1
- package/src/constants/validation-fields.js +1 -0
- package/src/mappers/business-details-mapper.js +48 -0
- package/src/mappers/mappers.js +3 -1
- package/src/presenters/business-details-presenter.js +67 -0
- package/src/presenters/presenters.js +12 -1
- package/src/schemas/business/business-email-schema.js +19 -0
- package/src/schemas/business/business-name-schema.js +13 -0
- package/src/schemas/business/business-phone-schema.js +33 -0
- package/src/schemas/business/business-schemas.js +12 -1
- package/src/schemas/business/business-vat-schema.js +11 -0
package/dist/index.cjs
CHANGED
|
@@ -87,11 +87,46 @@ var mapCustomerName = (name = {}) => {
|
|
|
87
87
|
};
|
|
88
88
|
};
|
|
89
89
|
|
|
90
|
+
// src/mappers/business-details-mapper.js
|
|
91
|
+
var asNullable = (value) => value ?? null;
|
|
92
|
+
var mapBusinessInfo = (business) => {
|
|
93
|
+
var _a, _b;
|
|
94
|
+
const info = business.info ?? {};
|
|
95
|
+
return {
|
|
96
|
+
sbi: business.sbi,
|
|
97
|
+
businessName: asNullable(info.name),
|
|
98
|
+
vat: asNullable(info.vat),
|
|
99
|
+
traderNumber: asNullable(info.traderNumber),
|
|
100
|
+
vendorNumber: asNullable(info.vendorNumber),
|
|
101
|
+
legalStatus: asNullable((_a = info.legalStatus) == null ? void 0 : _a.type),
|
|
102
|
+
type: asNullable((_b = info.type) == null ? void 0 : _b.type),
|
|
103
|
+
countyParishHoldingNumbers: business.countyParishHoldings ?? []
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
var mapBusinessContact = (businessInfo) => {
|
|
107
|
+
var _a, _b, _c;
|
|
108
|
+
return {
|
|
109
|
+
email: asNullable((_a = businessInfo.email) == null ? void 0 : _a.address),
|
|
110
|
+
landline: asNullable((_b = businessInfo.phone) == null ? void 0 : _b.landline),
|
|
111
|
+
mobile: asNullable((_c = businessInfo.phone) == null ? void 0 : _c.mobile)
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
var mapBusinessDetails = (value) => {
|
|
115
|
+
const business = (value == null ? void 0 : value.business) ?? {};
|
|
116
|
+
const businessInfo = business.info ?? {};
|
|
117
|
+
return {
|
|
118
|
+
info: mapBusinessInfo(business),
|
|
119
|
+
address: mapAddress(businessInfo.address),
|
|
120
|
+
contact: mapBusinessContact(businessInfo)
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
|
|
90
124
|
// src/mappers/mappers.js
|
|
91
125
|
var mappers = {
|
|
92
126
|
personalBusinessDetails: mapPersonalBusinessDetails,
|
|
93
127
|
address: mapAddress,
|
|
94
|
-
customerName: mapCustomerName
|
|
128
|
+
customerName: mapCustomerName,
|
|
129
|
+
businessDetails: mapBusinessDetails
|
|
95
130
|
};
|
|
96
131
|
|
|
97
132
|
// src/schemas/business/business-sbi-schema.js
|
|
@@ -109,6 +144,7 @@ var import_joi2 = __toESM(require("joi"), 1);
|
|
|
109
144
|
var FIRST_NAME_MAX = 100;
|
|
110
145
|
var LAST_NAME_MAX = 100;
|
|
111
146
|
var MIDDLE_NAMES_MAX = 100;
|
|
147
|
+
var BUSINESS_NAME_MAX = 160;
|
|
112
148
|
var EMAIL_MAX = 254;
|
|
113
149
|
var PHONE_NUMBER_MIN = 10;
|
|
114
150
|
var PHONE_NUMBER_MAX = 50;
|
|
@@ -152,16 +188,78 @@ var addressSchema = import_joi2.default.object({
|
|
|
152
188
|
})
|
|
153
189
|
});
|
|
154
190
|
|
|
191
|
+
// src/schemas/business/business-name-schema.js
|
|
192
|
+
var import_joi3 = __toESM(require("joi"), 1);
|
|
193
|
+
var businessNameSchema = import_joi3.default.object({
|
|
194
|
+
businessName: import_joi3.default.string().required().max(BUSINESS_NAME_MAX).messages({
|
|
195
|
+
"string.empty": "Enter business name",
|
|
196
|
+
"string.max": `Business name must be ${BUSINESS_NAME_MAX} characters or less`,
|
|
197
|
+
"any.required": "Enter business name"
|
|
198
|
+
})
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// src/schemas/business/business-email-schema.js
|
|
202
|
+
var import_joi4 = __toESM(require("joi"), 1);
|
|
203
|
+
var businessEmailSchema = import_joi4.default.object({
|
|
204
|
+
businessEmail: import_joi4.default.string().required().max(EMAIL_MAX).email({
|
|
205
|
+
minDomainSegments: 2,
|
|
206
|
+
tlds: {
|
|
207
|
+
allow: true
|
|
208
|
+
}
|
|
209
|
+
}).messages({
|
|
210
|
+
"string.max": `Business email address must be ${EMAIL_MAX} characters or less`,
|
|
211
|
+
"string.empty": "Enter business email address",
|
|
212
|
+
"string.email": "Enter an email address, like name@example.com"
|
|
213
|
+
})
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// src/schemas/business/business-phone-schema.js
|
|
217
|
+
var import_joi5 = __toESM(require("joi"), 1);
|
|
218
|
+
|
|
219
|
+
// src/constants/patterns.js
|
|
220
|
+
var PHONE_NUMBER_PATTERN = /^\+?[0-9 ()]+$/;
|
|
221
|
+
|
|
222
|
+
// src/schemas/business/business-phone-schema.js
|
|
223
|
+
var businessPhoneSchema = import_joi5.default.object({
|
|
224
|
+
businessTelephone: import_joi5.default.string().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
225
|
+
"string.min": `Business telephone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
226
|
+
"string.max": `Business telephone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
227
|
+
"string.pattern.base": "Business telephone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +"
|
|
228
|
+
}),
|
|
229
|
+
businessMobile: import_joi5.default.string().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
230
|
+
"string.min": `Business mobile phone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
231
|
+
"string.max": `Business mobile phone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
232
|
+
"string.pattern.base": "Business mobile phone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +"
|
|
233
|
+
})
|
|
234
|
+
}).or("businessTelephone", "businessMobile").messages({
|
|
235
|
+
"object.missing": "Enter at least one phone number"
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// src/schemas/business/business-vat-schema.js
|
|
239
|
+
var import_joi6 = __toESM(require("joi"), 1);
|
|
240
|
+
var businessVatSchema = import_joi6.default.object({
|
|
241
|
+
vatNumber: import_joi6.default.string().pattern(/^\d{9}$/).allow("").optional().messages({
|
|
242
|
+
"string.pattern.base": "Enter a VAT registration number, like 123456789"
|
|
243
|
+
})
|
|
244
|
+
});
|
|
245
|
+
|
|
155
246
|
// src/schemas/business/business-schemas.js
|
|
156
247
|
var businessSchemas = {
|
|
157
248
|
sbi: businessSbiSchema,
|
|
158
|
-
address: addressSchema
|
|
249
|
+
address: addressSchema,
|
|
250
|
+
details: {
|
|
251
|
+
name: businessNameSchema,
|
|
252
|
+
address: addressSchema,
|
|
253
|
+
phone: businessPhoneSchema,
|
|
254
|
+
email: businessEmailSchema,
|
|
255
|
+
vat: businessVatSchema
|
|
256
|
+
}
|
|
159
257
|
};
|
|
160
258
|
|
|
161
259
|
// src/schemas/customer/customer-crn-schema.js
|
|
162
|
-
var
|
|
163
|
-
var customerCrnSchema =
|
|
164
|
-
crn:
|
|
260
|
+
var import_joi7 = __toESM(require("joi"), 1);
|
|
261
|
+
var customerCrnSchema = import_joi7.default.object({
|
|
262
|
+
crn: import_joi7.default.string().pattern(/^\d{10}$/).allow("").optional().messages({
|
|
165
263
|
"string.pattern.base": "Enter the full CRN"
|
|
166
264
|
})
|
|
167
265
|
});
|
|
@@ -172,28 +270,25 @@ var customerSchemas = {
|
|
|
172
270
|
};
|
|
173
271
|
|
|
174
272
|
// src/schemas/personal/personal-name-schema.js
|
|
175
|
-
var
|
|
176
|
-
var personalNameSchema =
|
|
177
|
-
first:
|
|
273
|
+
var import_joi8 = __toESM(require("joi"), 1);
|
|
274
|
+
var personalNameSchema = import_joi8.default.object({
|
|
275
|
+
first: import_joi8.default.string().required().max(FIRST_NAME_MAX).messages({
|
|
178
276
|
"string.empty": "Enter first name",
|
|
179
277
|
"string.max": `First name must be ${FIRST_NAME_MAX} characters or less`,
|
|
180
278
|
"any.required": "Enter first name"
|
|
181
279
|
}),
|
|
182
|
-
last:
|
|
280
|
+
last: import_joi8.default.string().required().max(LAST_NAME_MAX).messages({
|
|
183
281
|
"string.empty": "Enter last name",
|
|
184
282
|
"string.max": `Last name must be ${LAST_NAME_MAX} characters or less`,
|
|
185
283
|
"any.required": "Enter last name"
|
|
186
284
|
}),
|
|
187
|
-
middle:
|
|
285
|
+
middle: import_joi8.default.string().allow("").max(MIDDLE_NAMES_MAX).messages({
|
|
188
286
|
"string.max": `Middle names must be ${MIDDLE_NAMES_MAX} characters or less`
|
|
189
287
|
})
|
|
190
288
|
});
|
|
191
289
|
|
|
192
290
|
// src/schemas/personal/personal-dob-schema.js
|
|
193
|
-
var
|
|
194
|
-
|
|
195
|
-
// src/constants/patterns.js
|
|
196
|
-
var PHONE_NUMBER_PATTERN = /^\+?[0-9 ()]+$/;
|
|
291
|
+
var import_joi9 = __toESM(require("joi"), 1);
|
|
197
292
|
|
|
198
293
|
// src/constants/month-map.js
|
|
199
294
|
var MONTH_MAP = {
|
|
@@ -224,10 +319,10 @@ var MONTH_MAP = {
|
|
|
224
319
|
};
|
|
225
320
|
|
|
226
321
|
// src/schemas/personal/personal-dob-schema.js
|
|
227
|
-
var personalDobSchema =
|
|
228
|
-
day:
|
|
229
|
-
month:
|
|
230
|
-
year:
|
|
322
|
+
var personalDobSchema = import_joi9.default.object({
|
|
323
|
+
day: import_joi9.default.string().allow(""),
|
|
324
|
+
month: import_joi9.default.string().allow(""),
|
|
325
|
+
year: import_joi9.default.string().allow("")
|
|
231
326
|
}).custom((value, helpers) => {
|
|
232
327
|
const { day, month, year } = value;
|
|
233
328
|
const missingFieldsError = checkMissingFields(day, month, year, helpers);
|
|
@@ -338,9 +433,9 @@ var makeError = (helpers, code, fields) => {
|
|
|
338
433
|
};
|
|
339
434
|
|
|
340
435
|
// src/schemas/personal/personal-email-schema.js
|
|
341
|
-
var
|
|
342
|
-
var personalEmailSchema =
|
|
343
|
-
personalEmail:
|
|
436
|
+
var import_joi10 = __toESM(require("joi"), 1);
|
|
437
|
+
var personalEmailSchema = import_joi10.default.object({
|
|
438
|
+
personalEmail: import_joi10.default.string().required().max(EMAIL_MAX).email({
|
|
344
439
|
minDomainSegments: 2,
|
|
345
440
|
tlds: {
|
|
346
441
|
allow: true,
|
|
@@ -354,14 +449,14 @@ var personalEmailSchema = import_joi6.default.object({
|
|
|
354
449
|
});
|
|
355
450
|
|
|
356
451
|
// src/schemas/personal/personal-phone-schema.js
|
|
357
|
-
var
|
|
358
|
-
var personalPhoneSchema =
|
|
359
|
-
personalTelephone:
|
|
452
|
+
var import_joi11 = __toESM(require("joi"), 1);
|
|
453
|
+
var personalPhoneSchema = import_joi11.default.object({
|
|
454
|
+
personalTelephone: import_joi11.default.string().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
360
455
|
"string.min": `Personal telephone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
361
456
|
"string.max": `Personal telephone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
362
457
|
"string.pattern.base": "Personal telephone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +"
|
|
363
458
|
}),
|
|
364
|
-
personalMobile:
|
|
459
|
+
personalMobile: import_joi11.default.string().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
365
460
|
"string.min": `Personal mobile phone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
366
461
|
"string.max": `Personal mobile phone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
367
462
|
"string.pattern.base": "Personal mobile phone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +"
|
|
@@ -555,6 +650,24 @@ var sortErrorsBySectionOrder = (errors, orderedSectionsToFix, SECTION_FIELD_ORDE
|
|
|
555
650
|
return sortedErrors;
|
|
556
651
|
};
|
|
557
652
|
|
|
653
|
+
// src/presenters/business-details-presenter.js
|
|
654
|
+
var getActionText = (value) => {
|
|
655
|
+
return value ? "Change" : "Add";
|
|
656
|
+
};
|
|
657
|
+
var formatCph = (countyParishHoldings) => {
|
|
658
|
+
return (countyParishHoldings || []).filter((cph) => cph == null ? void 0 : cph.cphNumber).map((cph) => cph.cphNumber);
|
|
659
|
+
};
|
|
660
|
+
var formatCphText = (count) => {
|
|
661
|
+
return `County Parish Holding (CPH) number${count !== 1 ? "s" : ""}`;
|
|
662
|
+
};
|
|
663
|
+
var formatBusinessAddress = (businessAddress) => {
|
|
664
|
+
var _a, _b;
|
|
665
|
+
if (((_a = businessAddress == null ? void 0 : businessAddress.lookup) == null ? void 0 : _a.uprn) || ((_b = businessAddress == null ? void 0 : businessAddress.manual) == null ? void 0 : _b.line1)) {
|
|
666
|
+
return formatDisplayAddress(businessAddress);
|
|
667
|
+
}
|
|
668
|
+
return [];
|
|
669
|
+
};
|
|
670
|
+
|
|
558
671
|
// src/presenters/presenters.js
|
|
559
672
|
var presenters = {
|
|
560
673
|
formatBackLink,
|
|
@@ -563,7 +676,11 @@ var presenters = {
|
|
|
563
676
|
formatOriginalAddress,
|
|
564
677
|
formatChangedAddress,
|
|
565
678
|
formatDisplayAddresses,
|
|
566
|
-
sortErrorsBySectionOrder
|
|
679
|
+
sortErrorsBySectionOrder,
|
|
680
|
+
getActionText,
|
|
681
|
+
formatCph,
|
|
682
|
+
formatCphText,
|
|
683
|
+
formatBusinessAddress
|
|
567
684
|
};
|
|
568
685
|
// Annotate the CommonJS export names for ESM import in node:
|
|
569
686
|
0 && (module.exports = {
|
package/dist/index.js
CHANGED
|
@@ -49,11 +49,46 @@ var mapCustomerName = (name = {}) => {
|
|
|
49
49
|
};
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
// src/mappers/business-details-mapper.js
|
|
53
|
+
var asNullable = (value) => value ?? null;
|
|
54
|
+
var mapBusinessInfo = (business) => {
|
|
55
|
+
var _a, _b;
|
|
56
|
+
const info = business.info ?? {};
|
|
57
|
+
return {
|
|
58
|
+
sbi: business.sbi,
|
|
59
|
+
businessName: asNullable(info.name),
|
|
60
|
+
vat: asNullable(info.vat),
|
|
61
|
+
traderNumber: asNullable(info.traderNumber),
|
|
62
|
+
vendorNumber: asNullable(info.vendorNumber),
|
|
63
|
+
legalStatus: asNullable((_a = info.legalStatus) == null ? void 0 : _a.type),
|
|
64
|
+
type: asNullable((_b = info.type) == null ? void 0 : _b.type),
|
|
65
|
+
countyParishHoldingNumbers: business.countyParishHoldings ?? []
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
var mapBusinessContact = (businessInfo) => {
|
|
69
|
+
var _a, _b, _c;
|
|
70
|
+
return {
|
|
71
|
+
email: asNullable((_a = businessInfo.email) == null ? void 0 : _a.address),
|
|
72
|
+
landline: asNullable((_b = businessInfo.phone) == null ? void 0 : _b.landline),
|
|
73
|
+
mobile: asNullable((_c = businessInfo.phone) == null ? void 0 : _c.mobile)
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
var mapBusinessDetails = (value) => {
|
|
77
|
+
const business = (value == null ? void 0 : value.business) ?? {};
|
|
78
|
+
const businessInfo = business.info ?? {};
|
|
79
|
+
return {
|
|
80
|
+
info: mapBusinessInfo(business),
|
|
81
|
+
address: mapAddress(businessInfo.address),
|
|
82
|
+
contact: mapBusinessContact(businessInfo)
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
|
|
52
86
|
// src/mappers/mappers.js
|
|
53
87
|
var mappers = {
|
|
54
88
|
personalBusinessDetails: mapPersonalBusinessDetails,
|
|
55
89
|
address: mapAddress,
|
|
56
|
-
customerName: mapCustomerName
|
|
90
|
+
customerName: mapCustomerName,
|
|
91
|
+
businessDetails: mapBusinessDetails
|
|
57
92
|
};
|
|
58
93
|
|
|
59
94
|
// src/schemas/business/business-sbi-schema.js
|
|
@@ -71,6 +106,7 @@ import Joi2 from "joi";
|
|
|
71
106
|
var FIRST_NAME_MAX = 100;
|
|
72
107
|
var LAST_NAME_MAX = 100;
|
|
73
108
|
var MIDDLE_NAMES_MAX = 100;
|
|
109
|
+
var BUSINESS_NAME_MAX = 160;
|
|
74
110
|
var EMAIL_MAX = 254;
|
|
75
111
|
var PHONE_NUMBER_MIN = 10;
|
|
76
112
|
var PHONE_NUMBER_MAX = 50;
|
|
@@ -114,16 +150,78 @@ var addressSchema = Joi2.object({
|
|
|
114
150
|
})
|
|
115
151
|
});
|
|
116
152
|
|
|
153
|
+
// src/schemas/business/business-name-schema.js
|
|
154
|
+
import Joi3 from "joi";
|
|
155
|
+
var businessNameSchema = Joi3.object({
|
|
156
|
+
businessName: Joi3.string().required().max(BUSINESS_NAME_MAX).messages({
|
|
157
|
+
"string.empty": "Enter business name",
|
|
158
|
+
"string.max": `Business name must be ${BUSINESS_NAME_MAX} characters or less`,
|
|
159
|
+
"any.required": "Enter business name"
|
|
160
|
+
})
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// src/schemas/business/business-email-schema.js
|
|
164
|
+
import Joi4 from "joi";
|
|
165
|
+
var businessEmailSchema = Joi4.object({
|
|
166
|
+
businessEmail: Joi4.string().required().max(EMAIL_MAX).email({
|
|
167
|
+
minDomainSegments: 2,
|
|
168
|
+
tlds: {
|
|
169
|
+
allow: true
|
|
170
|
+
}
|
|
171
|
+
}).messages({
|
|
172
|
+
"string.max": `Business email address must be ${EMAIL_MAX} characters or less`,
|
|
173
|
+
"string.empty": "Enter business email address",
|
|
174
|
+
"string.email": "Enter an email address, like name@example.com"
|
|
175
|
+
})
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// src/schemas/business/business-phone-schema.js
|
|
179
|
+
import Joi5 from "joi";
|
|
180
|
+
|
|
181
|
+
// src/constants/patterns.js
|
|
182
|
+
var PHONE_NUMBER_PATTERN = /^\+?[0-9 ()]+$/;
|
|
183
|
+
|
|
184
|
+
// src/schemas/business/business-phone-schema.js
|
|
185
|
+
var businessPhoneSchema = Joi5.object({
|
|
186
|
+
businessTelephone: Joi5.string().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
187
|
+
"string.min": `Business telephone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
188
|
+
"string.max": `Business telephone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
189
|
+
"string.pattern.base": "Business telephone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +"
|
|
190
|
+
}),
|
|
191
|
+
businessMobile: Joi5.string().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
192
|
+
"string.min": `Business mobile phone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
193
|
+
"string.max": `Business mobile phone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
194
|
+
"string.pattern.base": "Business mobile phone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +"
|
|
195
|
+
})
|
|
196
|
+
}).or("businessTelephone", "businessMobile").messages({
|
|
197
|
+
"object.missing": "Enter at least one phone number"
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// src/schemas/business/business-vat-schema.js
|
|
201
|
+
import Joi6 from "joi";
|
|
202
|
+
var businessVatSchema = Joi6.object({
|
|
203
|
+
vatNumber: Joi6.string().pattern(/^\d{9}$/).allow("").optional().messages({
|
|
204
|
+
"string.pattern.base": "Enter a VAT registration number, like 123456789"
|
|
205
|
+
})
|
|
206
|
+
});
|
|
207
|
+
|
|
117
208
|
// src/schemas/business/business-schemas.js
|
|
118
209
|
var businessSchemas = {
|
|
119
210
|
sbi: businessSbiSchema,
|
|
120
|
-
address: addressSchema
|
|
211
|
+
address: addressSchema,
|
|
212
|
+
details: {
|
|
213
|
+
name: businessNameSchema,
|
|
214
|
+
address: addressSchema,
|
|
215
|
+
phone: businessPhoneSchema,
|
|
216
|
+
email: businessEmailSchema,
|
|
217
|
+
vat: businessVatSchema
|
|
218
|
+
}
|
|
121
219
|
};
|
|
122
220
|
|
|
123
221
|
// src/schemas/customer/customer-crn-schema.js
|
|
124
|
-
import
|
|
125
|
-
var customerCrnSchema =
|
|
126
|
-
crn:
|
|
222
|
+
import Joi7 from "joi";
|
|
223
|
+
var customerCrnSchema = Joi7.object({
|
|
224
|
+
crn: Joi7.string().pattern(/^\d{10}$/).allow("").optional().messages({
|
|
127
225
|
"string.pattern.base": "Enter the full CRN"
|
|
128
226
|
})
|
|
129
227
|
});
|
|
@@ -134,28 +232,25 @@ var customerSchemas = {
|
|
|
134
232
|
};
|
|
135
233
|
|
|
136
234
|
// src/schemas/personal/personal-name-schema.js
|
|
137
|
-
import
|
|
138
|
-
var personalNameSchema =
|
|
139
|
-
first:
|
|
235
|
+
import Joi8 from "joi";
|
|
236
|
+
var personalNameSchema = Joi8.object({
|
|
237
|
+
first: Joi8.string().required().max(FIRST_NAME_MAX).messages({
|
|
140
238
|
"string.empty": "Enter first name",
|
|
141
239
|
"string.max": `First name must be ${FIRST_NAME_MAX} characters or less`,
|
|
142
240
|
"any.required": "Enter first name"
|
|
143
241
|
}),
|
|
144
|
-
last:
|
|
242
|
+
last: Joi8.string().required().max(LAST_NAME_MAX).messages({
|
|
145
243
|
"string.empty": "Enter last name",
|
|
146
244
|
"string.max": `Last name must be ${LAST_NAME_MAX} characters or less`,
|
|
147
245
|
"any.required": "Enter last name"
|
|
148
246
|
}),
|
|
149
|
-
middle:
|
|
247
|
+
middle: Joi8.string().allow("").max(MIDDLE_NAMES_MAX).messages({
|
|
150
248
|
"string.max": `Middle names must be ${MIDDLE_NAMES_MAX} characters or less`
|
|
151
249
|
})
|
|
152
250
|
});
|
|
153
251
|
|
|
154
252
|
// src/schemas/personal/personal-dob-schema.js
|
|
155
|
-
import
|
|
156
|
-
|
|
157
|
-
// src/constants/patterns.js
|
|
158
|
-
var PHONE_NUMBER_PATTERN = /^\+?[0-9 ()]+$/;
|
|
253
|
+
import Joi9 from "joi";
|
|
159
254
|
|
|
160
255
|
// src/constants/month-map.js
|
|
161
256
|
var MONTH_MAP = {
|
|
@@ -186,10 +281,10 @@ var MONTH_MAP = {
|
|
|
186
281
|
};
|
|
187
282
|
|
|
188
283
|
// src/schemas/personal/personal-dob-schema.js
|
|
189
|
-
var personalDobSchema =
|
|
190
|
-
day:
|
|
191
|
-
month:
|
|
192
|
-
year:
|
|
284
|
+
var personalDobSchema = Joi9.object({
|
|
285
|
+
day: Joi9.string().allow(""),
|
|
286
|
+
month: Joi9.string().allow(""),
|
|
287
|
+
year: Joi9.string().allow("")
|
|
193
288
|
}).custom((value, helpers) => {
|
|
194
289
|
const { day, month, year } = value;
|
|
195
290
|
const missingFieldsError = checkMissingFields(day, month, year, helpers);
|
|
@@ -300,9 +395,9 @@ var makeError = (helpers, code, fields) => {
|
|
|
300
395
|
};
|
|
301
396
|
|
|
302
397
|
// src/schemas/personal/personal-email-schema.js
|
|
303
|
-
import
|
|
304
|
-
var personalEmailSchema =
|
|
305
|
-
personalEmail:
|
|
398
|
+
import Joi10 from "joi";
|
|
399
|
+
var personalEmailSchema = Joi10.object({
|
|
400
|
+
personalEmail: Joi10.string().required().max(EMAIL_MAX).email({
|
|
306
401
|
minDomainSegments: 2,
|
|
307
402
|
tlds: {
|
|
308
403
|
allow: true,
|
|
@@ -316,14 +411,14 @@ var personalEmailSchema = Joi6.object({
|
|
|
316
411
|
});
|
|
317
412
|
|
|
318
413
|
// src/schemas/personal/personal-phone-schema.js
|
|
319
|
-
import
|
|
320
|
-
var personalPhoneSchema =
|
|
321
|
-
personalTelephone:
|
|
414
|
+
import Joi11 from "joi";
|
|
415
|
+
var personalPhoneSchema = Joi11.object({
|
|
416
|
+
personalTelephone: Joi11.string().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
322
417
|
"string.min": `Personal telephone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
323
418
|
"string.max": `Personal telephone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
324
419
|
"string.pattern.base": "Personal telephone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +"
|
|
325
420
|
}),
|
|
326
|
-
personalMobile:
|
|
421
|
+
personalMobile: Joi11.string().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
327
422
|
"string.min": `Personal mobile phone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
328
423
|
"string.max": `Personal mobile phone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
329
424
|
"string.pattern.base": "Personal mobile phone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +"
|
|
@@ -517,6 +612,24 @@ var sortErrorsBySectionOrder = (errors, orderedSectionsToFix, SECTION_FIELD_ORDE
|
|
|
517
612
|
return sortedErrors;
|
|
518
613
|
};
|
|
519
614
|
|
|
615
|
+
// src/presenters/business-details-presenter.js
|
|
616
|
+
var getActionText = (value) => {
|
|
617
|
+
return value ? "Change" : "Add";
|
|
618
|
+
};
|
|
619
|
+
var formatCph = (countyParishHoldings) => {
|
|
620
|
+
return (countyParishHoldings || []).filter((cph) => cph == null ? void 0 : cph.cphNumber).map((cph) => cph.cphNumber);
|
|
621
|
+
};
|
|
622
|
+
var formatCphText = (count) => {
|
|
623
|
+
return `County Parish Holding (CPH) number${count !== 1 ? "s" : ""}`;
|
|
624
|
+
};
|
|
625
|
+
var formatBusinessAddress = (businessAddress) => {
|
|
626
|
+
var _a, _b;
|
|
627
|
+
if (((_a = businessAddress == null ? void 0 : businessAddress.lookup) == null ? void 0 : _a.uprn) || ((_b = businessAddress == null ? void 0 : businessAddress.manual) == null ? void 0 : _b.line1)) {
|
|
628
|
+
return formatDisplayAddress(businessAddress);
|
|
629
|
+
}
|
|
630
|
+
return [];
|
|
631
|
+
};
|
|
632
|
+
|
|
520
633
|
// src/presenters/presenters.js
|
|
521
634
|
var presenters = {
|
|
522
635
|
formatBackLink,
|
|
@@ -525,7 +638,11 @@ var presenters = {
|
|
|
525
638
|
formatOriginalAddress,
|
|
526
639
|
formatChangedAddress,
|
|
527
640
|
formatDisplayAddresses,
|
|
528
|
-
sortErrorsBySectionOrder
|
|
641
|
+
sortErrorsBySectionOrder,
|
|
642
|
+
getActionText,
|
|
643
|
+
formatCph,
|
|
644
|
+
formatCphText,
|
|
645
|
+
formatBusinessAddress
|
|
529
646
|
};
|
|
530
647
|
export {
|
|
531
648
|
mappers,
|
package/package.json
CHANGED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Takes the raw business details data from the DAL and maps it to a more usable format.
|
|
3
|
+
*
|
|
4
|
+
* Maps the core `info`, `address`, and `contact` fields.
|
|
5
|
+
* Callers that need additional fields (e.g. `customer`) should extend the result.
|
|
6
|
+
*
|
|
7
|
+
* @param {Object} value - The raw data from the DAL
|
|
8
|
+
*
|
|
9
|
+
* @returns {Object} Mapped business details with `info`, `address`, and `contact`
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { mapAddress } from './address-mapper.js'
|
|
13
|
+
|
|
14
|
+
const asNullable = (value) => value ?? null
|
|
15
|
+
|
|
16
|
+
const mapBusinessInfo = (business) => {
|
|
17
|
+
const info = business.info ?? {}
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
sbi: business.sbi,
|
|
21
|
+
businessName: asNullable(info.name),
|
|
22
|
+
vat: asNullable(info.vat),
|
|
23
|
+
traderNumber: asNullable(info.traderNumber),
|
|
24
|
+
vendorNumber: asNullable(info.vendorNumber),
|
|
25
|
+
legalStatus: asNullable(info.legalStatus?.type),
|
|
26
|
+
type: asNullable(info.type?.type),
|
|
27
|
+
countyParishHoldingNumbers: business.countyParishHoldings ?? []
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const mapBusinessContact = (businessInfo) => {
|
|
32
|
+
return {
|
|
33
|
+
email: asNullable(businessInfo.email?.address),
|
|
34
|
+
landline: asNullable(businessInfo.phone?.landline),
|
|
35
|
+
mobile: asNullable(businessInfo.phone?.mobile)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const mapBusinessDetails = (value) => {
|
|
40
|
+
const business = value?.business ?? {}
|
|
41
|
+
const businessInfo = business.info ?? {}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
info: mapBusinessInfo(business),
|
|
45
|
+
address: mapAddress(businessInfo.address),
|
|
46
|
+
contact: mapBusinessContact(businessInfo)
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/mappers/mappers.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { mapPersonalBusinessDetails } from './personal-business-details-mapper.js'
|
|
2
2
|
import { mapAddress } from './address-mapper.js'
|
|
3
3
|
import { mapCustomerName } from './customer-name-mapper.js'
|
|
4
|
+
import { mapBusinessDetails } from './business-details-mapper.js'
|
|
4
5
|
|
|
5
6
|
export const mappers = {
|
|
6
7
|
personalBusinessDetails: mapPersonalBusinessDetails,
|
|
7
8
|
address: mapAddress,
|
|
8
|
-
customerName: mapCustomerName
|
|
9
|
+
customerName: mapCustomerName,
|
|
10
|
+
businessDetails: mapBusinessDetails
|
|
9
11
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared presenter helpers for the "View and update your business details" page.
|
|
3
|
+
*
|
|
4
|
+
* These functions are identical across the internal and external frontend
|
|
5
|
+
* applications and are provided here to avoid duplication.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { formatDisplayAddress } from './base-presenter.js'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Returns the action text for a summary-list row.
|
|
12
|
+
*
|
|
13
|
+
* Returns 'Change' when a value is already present, or 'Add' when it is absent.
|
|
14
|
+
*
|
|
15
|
+
* @param {*} value - The current field value
|
|
16
|
+
*
|
|
17
|
+
* @returns {'Change'|'Add'}
|
|
18
|
+
*/
|
|
19
|
+
export const getActionText = (value) => {
|
|
20
|
+
return value ? 'Change' : 'Add'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Extracts an array of CPH number strings from the raw DAL response.
|
|
25
|
+
*
|
|
26
|
+
* Filters out any objects that have a null or undefined `cphNumber` property.
|
|
27
|
+
*
|
|
28
|
+
* @param {Array<Object>} countyParishHoldings - Raw CPH objects from the DAL
|
|
29
|
+
*
|
|
30
|
+
* @returns {string[]} Array of CPH number strings
|
|
31
|
+
*/
|
|
32
|
+
export const formatCph = (countyParishHoldings) => {
|
|
33
|
+
return (countyParishHoldings || [])
|
|
34
|
+
.filter((cph) => cph?.cphNumber)
|
|
35
|
+
.map((cph) => cph.cphNumber)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Returns the heading text for the CPH summary-list row.
|
|
40
|
+
*
|
|
41
|
+
* Uses the singular form when `count` is 1, plural otherwise.
|
|
42
|
+
*
|
|
43
|
+
* @param {number} count - Number of CPH numbers
|
|
44
|
+
*
|
|
45
|
+
* @returns {string}
|
|
46
|
+
*/
|
|
47
|
+
export const formatCphText = (count) => {
|
|
48
|
+
return `County Parish Holding (CPH) number${count !== 1 ? 's' : ''}`
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Formats a business address object into an array of display lines.
|
|
53
|
+
*
|
|
54
|
+
* Returns an empty array when the address contains no recognised content
|
|
55
|
+
* (i.e. neither a UPRN from a lookup nor a manually entered first line).
|
|
56
|
+
*
|
|
57
|
+
* @param {Object} businessAddress - The mapped address object
|
|
58
|
+
*
|
|
59
|
+
* @returns {string[]} Array of address lines, or an empty array if absent
|
|
60
|
+
*/
|
|
61
|
+
export const formatBusinessAddress = (businessAddress) => {
|
|
62
|
+
if (businessAddress?.lookup?.uprn || businessAddress?.manual?.line1) {
|
|
63
|
+
return formatDisplayAddress(businessAddress)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return []
|
|
67
|
+
}
|
|
@@ -8,6 +8,13 @@ import {
|
|
|
8
8
|
sortErrorsBySectionOrder
|
|
9
9
|
} from './base-presenter.js'
|
|
10
10
|
|
|
11
|
+
import {
|
|
12
|
+
getActionText,
|
|
13
|
+
formatCph,
|
|
14
|
+
formatCphText,
|
|
15
|
+
formatBusinessAddress
|
|
16
|
+
} from './business-details-presenter.js'
|
|
17
|
+
|
|
11
18
|
export const presenters = {
|
|
12
19
|
formatBackLink,
|
|
13
20
|
formatNumber,
|
|
@@ -15,5 +22,9 @@ export const presenters = {
|
|
|
15
22
|
formatOriginalAddress,
|
|
16
23
|
formatChangedAddress,
|
|
17
24
|
formatDisplayAddresses,
|
|
18
|
-
sortErrorsBySectionOrder
|
|
25
|
+
sortErrorsBySectionOrder,
|
|
26
|
+
getActionText,
|
|
27
|
+
formatCph,
|
|
28
|
+
formatCphText,
|
|
29
|
+
formatBusinessAddress
|
|
19
30
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Joi from 'joi'
|
|
2
|
+
import { EMAIL_MAX } from '../../constants/validation-fields.js'
|
|
3
|
+
|
|
4
|
+
export const businessEmailSchema = Joi.object({
|
|
5
|
+
businessEmail: Joi.string()
|
|
6
|
+
.required()
|
|
7
|
+
.max(EMAIL_MAX)
|
|
8
|
+
.email({
|
|
9
|
+
minDomainSegments: 2,
|
|
10
|
+
tlds: {
|
|
11
|
+
allow: true
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
.messages({
|
|
15
|
+
'string.max': `Business email address must be ${EMAIL_MAX} characters or less`,
|
|
16
|
+
'string.empty': 'Enter business email address',
|
|
17
|
+
'string.email': 'Enter an email address, like name@example.com'
|
|
18
|
+
})
|
|
19
|
+
})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Joi from 'joi'
|
|
2
|
+
import { BUSINESS_NAME_MAX } from '../../constants/validation-fields.js'
|
|
3
|
+
|
|
4
|
+
export const businessNameSchema = Joi.object({
|
|
5
|
+
businessName: Joi.string()
|
|
6
|
+
.required()
|
|
7
|
+
.max(BUSINESS_NAME_MAX)
|
|
8
|
+
.messages({
|
|
9
|
+
'string.empty': 'Enter business name',
|
|
10
|
+
'string.max': `Business name must be ${BUSINESS_NAME_MAX} characters or less`,
|
|
11
|
+
'any.required': 'Enter business name'
|
|
12
|
+
})
|
|
13
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import Joi from 'joi'
|
|
2
|
+
import {
|
|
3
|
+
PHONE_NUMBER_MIN,
|
|
4
|
+
PHONE_NUMBER_MAX
|
|
5
|
+
} from '../../constants/validation-fields.js'
|
|
6
|
+
import { PHONE_NUMBER_PATTERN } from '../../constants/patterns.js'
|
|
7
|
+
|
|
8
|
+
export const businessPhoneSchema = Joi.object({
|
|
9
|
+
businessTelephone: Joi.string()
|
|
10
|
+
.empty('')
|
|
11
|
+
.min(PHONE_NUMBER_MIN)
|
|
12
|
+
.max(PHONE_NUMBER_MAX)
|
|
13
|
+
.pattern(PHONE_NUMBER_PATTERN)
|
|
14
|
+
.messages({
|
|
15
|
+
'string.min': `Business telephone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
16
|
+
'string.max': `Business telephone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
17
|
+
'string.pattern.base': 'Business telephone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +'
|
|
18
|
+
}),
|
|
19
|
+
businessMobile: Joi.string()
|
|
20
|
+
.empty('')
|
|
21
|
+
.min(PHONE_NUMBER_MIN)
|
|
22
|
+
.max(PHONE_NUMBER_MAX)
|
|
23
|
+
.pattern(PHONE_NUMBER_PATTERN)
|
|
24
|
+
.messages({
|
|
25
|
+
'string.min': `Business mobile phone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
26
|
+
'string.max': `Business mobile phone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
27
|
+
'string.pattern.base': 'Business mobile phone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +'
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
.or('businessTelephone', 'businessMobile')
|
|
31
|
+
.messages({
|
|
32
|
+
'object.missing': 'Enter at least one phone number'
|
|
33
|
+
})
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import { businessSbiSchema } from './business-sbi-schema.js'
|
|
2
2
|
import { addressSchema } from '../address-schema.js'
|
|
3
|
+
import { businessNameSchema } from './business-name-schema.js'
|
|
4
|
+
import { businessEmailSchema } from './business-email-schema.js'
|
|
5
|
+
import { businessPhoneSchema } from './business-phone-schema.js'
|
|
6
|
+
import { businessVatSchema } from './business-vat-schema.js'
|
|
3
7
|
|
|
4
8
|
export const businessSchemas = {
|
|
5
9
|
sbi: businessSbiSchema,
|
|
6
|
-
address: addressSchema
|
|
10
|
+
address: addressSchema,
|
|
11
|
+
details: {
|
|
12
|
+
name: businessNameSchema,
|
|
13
|
+
address: addressSchema,
|
|
14
|
+
phone: businessPhoneSchema,
|
|
15
|
+
email: businessEmailSchema,
|
|
16
|
+
vat: businessVatSchema
|
|
17
|
+
}
|
|
7
18
|
}
|