@defra/fcp-sfd-frontend-engine 0.18.0 → 0.19.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 +928 -612
- package/dist/index.js +927 -612
- package/package.json +1 -1
- package/src/constants/country-names.js +8 -0
- package/src/index.js +1 -0
- package/src/mappers/address-lookup-mapper.js +79 -0
- package/src/mappers/mappers.js +3 -1
- package/src/mock-data/mock-os-places-addresses.js +146 -0
- package/src/services/os-places/address-lookup-service.js +202 -0
- package/src/services/os-places/os-places-stub.js +37 -0
- package/src/services/services.js +5 -0
package/dist/index.cjs
CHANGED
|
@@ -34,6 +34,7 @@ __export(index_exports, {
|
|
|
34
34
|
mutations: () => mutations,
|
|
35
35
|
presenters: () => presenters,
|
|
36
36
|
schemas: () => schemas,
|
|
37
|
+
services: () => services,
|
|
37
38
|
utils: () => utils
|
|
38
39
|
});
|
|
39
40
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -224,338 +225,6 @@ var mapBusinessDetails = (value) => {
|
|
|
224
225
|
};
|
|
225
226
|
};
|
|
226
227
|
|
|
227
|
-
// src/mappers/mappers.js
|
|
228
|
-
var mappers = {
|
|
229
|
-
personalBusinessDetails: mapPersonalBusinessDetails,
|
|
230
|
-
address: mapAddress,
|
|
231
|
-
customerName: mapCustomerName,
|
|
232
|
-
businessDetails: mapBusinessDetails
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
// src/mutations/business/update-business-email.js
|
|
236
|
-
var updateBusinessEmailMutation = `
|
|
237
|
-
mutation Mutation($input: UpdateBusinessEmailInput!) {
|
|
238
|
-
updateBusinessEmail(input: $input) {
|
|
239
|
-
business {
|
|
240
|
-
info {
|
|
241
|
-
email {
|
|
242
|
-
address
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
success
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
`;
|
|
250
|
-
|
|
251
|
-
// src/mutations/business/update-business-name.js
|
|
252
|
-
var updateBusinessNameMutation = `
|
|
253
|
-
mutation UpdateBusinessName($input: UpdateBusinessNameInput!) {
|
|
254
|
-
updateBusinessName(input: $input) {
|
|
255
|
-
business {
|
|
256
|
-
info {
|
|
257
|
-
name
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
success
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
`;
|
|
264
|
-
|
|
265
|
-
// src/mutations/personal/update-customer-name.js
|
|
266
|
-
var updateCustomerNameMutation = `
|
|
267
|
-
mutation UpdateCustomerName($input: UpdateCustomerNameInput!) {
|
|
268
|
-
updateCustomerName(input: $input) {
|
|
269
|
-
customer {
|
|
270
|
-
info {
|
|
271
|
-
name {
|
|
272
|
-
first
|
|
273
|
-
last
|
|
274
|
-
middle
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
`;
|
|
281
|
-
|
|
282
|
-
// src/mutations/personal/update-customer-dob.js
|
|
283
|
-
var updateCustomerDobMutation = `
|
|
284
|
-
mutation UpdateCustomerDateOfBirth($input: UpdateCustomerDateOfBirthInput!) {
|
|
285
|
-
updateCustomerDateOfBirth(input: $input) {
|
|
286
|
-
customer {
|
|
287
|
-
info {
|
|
288
|
-
dateOfBirth
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
`;
|
|
294
|
-
|
|
295
|
-
// src/mutations/personal/update-customer-phone.js
|
|
296
|
-
var updateCustomerPhoneMutation = `
|
|
297
|
-
mutation UpdateCustomerPhone($input: UpdateCustomerPhoneInput!) {
|
|
298
|
-
updateCustomerPhone(input: $input) {
|
|
299
|
-
customer {
|
|
300
|
-
info {
|
|
301
|
-
phone {
|
|
302
|
-
landline
|
|
303
|
-
mobile
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
`;
|
|
310
|
-
|
|
311
|
-
// src/mutations/personal/update-customer-email.js
|
|
312
|
-
var updateCustomerEmailMutation = `
|
|
313
|
-
mutation UpdateCustomerEmail($input: UpdateCustomerEmailInput!) {
|
|
314
|
-
updateCustomerEmail(input: $input) {
|
|
315
|
-
customer {
|
|
316
|
-
info {
|
|
317
|
-
email {
|
|
318
|
-
address
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
`;
|
|
325
|
-
|
|
326
|
-
// src/mutations/mutations.js
|
|
327
|
-
var mutations = {
|
|
328
|
-
updateBusinessEmail: updateBusinessEmailMutation,
|
|
329
|
-
updateBusinessName: updateBusinessNameMutation,
|
|
330
|
-
updateCustomerName: updateCustomerNameMutation,
|
|
331
|
-
updateCustomerDob: updateCustomerDobMutation,
|
|
332
|
-
updateCustomerPhone: updateCustomerPhoneMutation,
|
|
333
|
-
updateCustomerEmail: updateCustomerEmailMutation
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
// src/presenters/base-presenter.js
|
|
337
|
-
var BACK_LINK_DISPLAY_MAX = 50;
|
|
338
|
-
var formatBackLink = (businessName) => {
|
|
339
|
-
if (businessName.length > BACK_LINK_DISPLAY_MAX) {
|
|
340
|
-
return `Back to ${businessName.slice(0, BACK_LINK_DISPLAY_MAX)}\u2026`;
|
|
341
|
-
}
|
|
342
|
-
return `Back to ${businessName}`;
|
|
343
|
-
};
|
|
344
|
-
var formatNumber = (payloadNumber, changedNumber, originalNumber) => {
|
|
345
|
-
if (payloadNumber !== void 0) {
|
|
346
|
-
return payloadNumber;
|
|
347
|
-
}
|
|
348
|
-
if (changedNumber !== void 0) {
|
|
349
|
-
return changedNumber;
|
|
350
|
-
}
|
|
351
|
-
return originalNumber;
|
|
352
|
-
};
|
|
353
|
-
var formatDatePart = (changed, original) => {
|
|
354
|
-
return changed ?? (original == null ? void 0 : original.toString()) ?? "";
|
|
355
|
-
};
|
|
356
|
-
var formatDateInputValues = (payloadDob, changedDob, originalDob) => {
|
|
357
|
-
if (payloadDob) {
|
|
358
|
-
return {
|
|
359
|
-
day: payloadDob.day ?? "",
|
|
360
|
-
month: payloadDob.month ?? "",
|
|
361
|
-
year: payloadDob.year ?? ""
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
return {
|
|
365
|
-
day: formatDatePart(changedDob == null ? void 0 : changedDob.day, originalDob == null ? void 0 : originalDob.day),
|
|
366
|
-
month: formatDatePart(changedDob == null ? void 0 : changedDob.month, originalDob == null ? void 0 : originalDob.month),
|
|
367
|
-
year: formatDatePart(changedDob == null ? void 0 : changedDob.year, originalDob == null ? void 0 : originalDob.year)
|
|
368
|
-
};
|
|
369
|
-
};
|
|
370
|
-
var sortErrorsBySectionOrder = (errors, orderedSectionsToFix, SECTION_FIELD_ORDER) => {
|
|
371
|
-
const sortedErrors = [];
|
|
372
|
-
for (const section of orderedSectionsToFix) {
|
|
373
|
-
const fieldsInSection = SECTION_FIELD_ORDER[section] || [];
|
|
374
|
-
for (const field of fieldsInSection) {
|
|
375
|
-
if (errors[field]) {
|
|
376
|
-
sortedErrors.push({
|
|
377
|
-
field,
|
|
378
|
-
...errors[field]
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
return sortedErrors;
|
|
384
|
-
};
|
|
385
|
-
|
|
386
|
-
// src/presenters/address-presenter.js
|
|
387
|
-
var addressChangeLink = (postcodeLookup, context) => {
|
|
388
|
-
if (context === "business") {
|
|
389
|
-
if (postcodeLookup) {
|
|
390
|
-
return "/business-address-change";
|
|
391
|
-
}
|
|
392
|
-
return "/business-address-enter";
|
|
393
|
-
}
|
|
394
|
-
if (context === "personal") {
|
|
395
|
-
if (postcodeLookup) {
|
|
396
|
-
return "/account-address-change";
|
|
397
|
-
}
|
|
398
|
-
return "/account-address-enter";
|
|
399
|
-
}
|
|
400
|
-
return null;
|
|
401
|
-
};
|
|
402
|
-
var addressBackLink = (postcodeLookup, context) => {
|
|
403
|
-
if (context === "business") {
|
|
404
|
-
if (postcodeLookup) {
|
|
405
|
-
return { href: "/business-address-select" };
|
|
406
|
-
}
|
|
407
|
-
return { href: "/business-address-enter" };
|
|
408
|
-
}
|
|
409
|
-
if (context === "personal") {
|
|
410
|
-
if (postcodeLookup) {
|
|
411
|
-
return { href: "/account-address-select" };
|
|
412
|
-
}
|
|
413
|
-
return { href: "/account-address-enter" };
|
|
414
|
-
}
|
|
415
|
-
return null;
|
|
416
|
-
};
|
|
417
|
-
var buildAddressLine = (parts) => {
|
|
418
|
-
return parts.filter(Boolean).join(", ") || null;
|
|
419
|
-
};
|
|
420
|
-
var buildStreetLine = (buildingRange, street) => {
|
|
421
|
-
return [buildingRange, street].filter(Boolean).join(" ") || null;
|
|
422
|
-
};
|
|
423
|
-
var formatLookupAddress = (lookup, city, country, postcode) => ({
|
|
424
|
-
address1: buildAddressLine([lookup.pafOrganisationName, lookup.flatName, lookup.buildingName]),
|
|
425
|
-
address2: buildStreetLine(lookup.buildingNumberRange, lookup.street),
|
|
426
|
-
address3: buildAddressLine([lookup.doubleDependentLocality, lookup.dependentLocality]),
|
|
427
|
-
county: lookup.county ?? null,
|
|
428
|
-
city: city ?? null,
|
|
429
|
-
country: country ?? null,
|
|
430
|
-
postcode: postcode ?? null
|
|
431
|
-
});
|
|
432
|
-
var formatManualAddress = (manual, city, country, postcode) => ({
|
|
433
|
-
address1: manual.line1 ?? null,
|
|
434
|
-
address2: manual.line2 ?? null,
|
|
435
|
-
address3: manual.line3 ?? null,
|
|
436
|
-
city: city ?? null,
|
|
437
|
-
county: manual.line4 ?? null,
|
|
438
|
-
country: country ?? null,
|
|
439
|
-
postcode: postcode ?? null
|
|
440
|
-
});
|
|
441
|
-
var formatDisplayAddress = (address) => {
|
|
442
|
-
const { lookup, manual, postcode, country, city } = address;
|
|
443
|
-
let addressLines = [];
|
|
444
|
-
if (lookup.uprn) {
|
|
445
|
-
const buildingAndStreet = [
|
|
446
|
-
lookup.buildingNumberRange,
|
|
447
|
-
lookup.street
|
|
448
|
-
].filter(Boolean).join(" ");
|
|
449
|
-
addressLines = [
|
|
450
|
-
lookup.pafOrganisationName,
|
|
451
|
-
lookup.flatName,
|
|
452
|
-
lookup.buildingName,
|
|
453
|
-
buildingAndStreet,
|
|
454
|
-
lookup.doubleDependentLocality,
|
|
455
|
-
lookup.dependentLocality,
|
|
456
|
-
city,
|
|
457
|
-
lookup.county
|
|
458
|
-
];
|
|
459
|
-
} else {
|
|
460
|
-
addressLines = [
|
|
461
|
-
manual.line1,
|
|
462
|
-
manual.line2,
|
|
463
|
-
manual.line3,
|
|
464
|
-
city,
|
|
465
|
-
manual.line4,
|
|
466
|
-
// County
|
|
467
|
-
manual.line5
|
|
468
|
-
];
|
|
469
|
-
}
|
|
470
|
-
return [
|
|
471
|
-
...addressLines.filter(Boolean),
|
|
472
|
-
postcode,
|
|
473
|
-
country
|
|
474
|
-
];
|
|
475
|
-
};
|
|
476
|
-
var formatOriginalAddress = (originalAddress) => {
|
|
477
|
-
const { lookup, manual, city, country, postcode } = originalAddress;
|
|
478
|
-
return lookup.uprn ? formatLookupAddress(lookup, city, country, postcode) : formatManualAddress(manual, city, country, postcode);
|
|
479
|
-
};
|
|
480
|
-
var formatChangedAddress = (changeBusinessAddress) => {
|
|
481
|
-
if (!changeBusinessAddress.uprn) {
|
|
482
|
-
return changeBusinessAddress;
|
|
483
|
-
}
|
|
484
|
-
const {
|
|
485
|
-
pafOrganisationName,
|
|
486
|
-
flatName,
|
|
487
|
-
buildingName,
|
|
488
|
-
buildingNumberRange,
|
|
489
|
-
street,
|
|
490
|
-
doubleDependentLocality,
|
|
491
|
-
dependentLocality,
|
|
492
|
-
city,
|
|
493
|
-
county,
|
|
494
|
-
country,
|
|
495
|
-
postcode
|
|
496
|
-
} = changeBusinessAddress;
|
|
497
|
-
return {
|
|
498
|
-
address1: buildAddressLine([pafOrganisationName, flatName, buildingName]),
|
|
499
|
-
address2: buildStreetLine(buildingNumberRange, street),
|
|
500
|
-
address3: buildAddressLine([doubleDependentLocality, dependentLocality]),
|
|
501
|
-
city: city ?? null,
|
|
502
|
-
county: county ?? null,
|
|
503
|
-
country: country ?? null,
|
|
504
|
-
postcode: postcode ?? null
|
|
505
|
-
};
|
|
506
|
-
};
|
|
507
|
-
var formatDisplayAddresses = (addresses, previouslyPickedAddress) => {
|
|
508
|
-
const displayAddresses = addresses.map((address) => ({
|
|
509
|
-
value: `${address.uprn}${address.displayAddress}`,
|
|
510
|
-
text: address.displayAddress,
|
|
511
|
-
selected: (previouslyPickedAddress == null ? void 0 : previouslyPickedAddress.uprn) === address.uprn && (previouslyPickedAddress == null ? void 0 : previouslyPickedAddress.displayAddress) === address.displayAddress
|
|
512
|
-
}));
|
|
513
|
-
const hasSelectedAddress = displayAddresses.some((addr) => addr.selected);
|
|
514
|
-
const text = addresses.length === 1 ? "1 address found" : `${addresses.length} addresses found`;
|
|
515
|
-
displayAddresses.unshift({
|
|
516
|
-
value: "display",
|
|
517
|
-
text,
|
|
518
|
-
selected: !hasSelectedAddress
|
|
519
|
-
});
|
|
520
|
-
return displayAddresses;
|
|
521
|
-
};
|
|
522
|
-
|
|
523
|
-
// src/presenters/business-details-presenter.js
|
|
524
|
-
var getActionText = (value) => {
|
|
525
|
-
return value ? "Change" : "Add";
|
|
526
|
-
};
|
|
527
|
-
var formatCph = (countyParishHoldings) => {
|
|
528
|
-
return (countyParishHoldings || []).filter((cph) => cph == null ? void 0 : cph.cphNumber).map((cph) => cph.cphNumber);
|
|
529
|
-
};
|
|
530
|
-
var formatCphText = (count) => {
|
|
531
|
-
return `County Parish Holding (CPH) number${count !== 1 ? "s" : ""}`;
|
|
532
|
-
};
|
|
533
|
-
var formatBusinessAddress = (businessAddress) => {
|
|
534
|
-
var _a, _b;
|
|
535
|
-
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)) {
|
|
536
|
-
return formatDisplayAddress(businessAddress);
|
|
537
|
-
}
|
|
538
|
-
return [];
|
|
539
|
-
};
|
|
540
|
-
|
|
541
|
-
// src/presenters/presenters.js
|
|
542
|
-
var presenters = {
|
|
543
|
-
formatBackLink,
|
|
544
|
-
formatNumber,
|
|
545
|
-
formatDateInputValues,
|
|
546
|
-
formatDisplayAddress,
|
|
547
|
-
formatOriginalAddress,
|
|
548
|
-
formatChangedAddress,
|
|
549
|
-
formatDisplayAddresses,
|
|
550
|
-
sortErrorsBySectionOrder,
|
|
551
|
-
getActionText,
|
|
552
|
-
formatCph,
|
|
553
|
-
formatCphText,
|
|
554
|
-
formatBusinessAddress,
|
|
555
|
-
addressBackLink,
|
|
556
|
-
addressChangeLink
|
|
557
|
-
};
|
|
558
|
-
|
|
559
228
|
// src/utils/joi.js
|
|
560
229
|
var import_joi = __toESM(require("joi"), 1);
|
|
561
230
|
var Joi = import_joi.default.extend((joi) => ({
|
|
@@ -630,332 +299,731 @@ var businessNameSchema = Joi.object({
|
|
|
630
299
|
})
|
|
631
300
|
});
|
|
632
301
|
|
|
633
|
-
// src/schemas/business/business-email-schema.js
|
|
634
|
-
var businessEmailSchema = Joi.object({
|
|
635
|
-
businessEmail: Joi.string().required().max(EMAIL_MAX).email({
|
|
302
|
+
// src/schemas/business/business-email-schema.js
|
|
303
|
+
var businessEmailSchema = Joi.object({
|
|
304
|
+
businessEmail: Joi.string().required().max(EMAIL_MAX).email({
|
|
305
|
+
minDomainSegments: 2,
|
|
306
|
+
tlds: {
|
|
307
|
+
allow: true
|
|
308
|
+
}
|
|
309
|
+
}).messages({
|
|
310
|
+
"string.max": `Business email address must be ${EMAIL_MAX} characters or less`,
|
|
311
|
+
"string.empty": "Enter business email address",
|
|
312
|
+
"string.email": "Enter an email address, like name@example.com",
|
|
313
|
+
"string.noControlChars": "Business email address must not contain invalid characters"
|
|
314
|
+
})
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// src/schemas/business/business-phone-schema.js
|
|
318
|
+
var businessPhoneSchema = Joi.object({
|
|
319
|
+
businessTelephone: Joi.string().trim().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
320
|
+
"string.min": `Business telephone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
321
|
+
"string.max": `Business telephone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
322
|
+
"string.pattern.base": "Business telephone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +",
|
|
323
|
+
"string.noControlChars": "Business telephone number must not contain invalid characters"
|
|
324
|
+
}),
|
|
325
|
+
businessMobile: Joi.string().trim().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
326
|
+
"string.min": `Business mobile phone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
327
|
+
"string.max": `Business mobile phone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
328
|
+
"string.pattern.base": "Business mobile phone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +",
|
|
329
|
+
"string.noControlChars": "Business mobile phone number must not contain invalid characters"
|
|
330
|
+
})
|
|
331
|
+
}).or("businessTelephone", "businessMobile").messages({
|
|
332
|
+
"object.missing": "Enter at least one phone number"
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
// src/schemas/business/business-vat-schema.js
|
|
336
|
+
var businessVatSchema = Joi.object({
|
|
337
|
+
vatNumber: Joi.string().pattern(/^\d{9}$/).allow("").optional().messages({
|
|
338
|
+
"string.pattern.base": "Enter a VAT registration number, like 123456789",
|
|
339
|
+
"string.noControlChars": "VAT registration number must not contain invalid characters"
|
|
340
|
+
})
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
// src/schemas/business/business-vat-change-schema.js
|
|
344
|
+
var businessVatChangeSchema = Joi.object({
|
|
345
|
+
vatNumber: Joi.string().pattern(/^\d{9}$/).required().messages({
|
|
346
|
+
"string.pattern.base": "Enter a VAT registration number, like 123456789",
|
|
347
|
+
"string.empty": "Enter a VAT registration number",
|
|
348
|
+
"any.required": "Enter a VAT registration number",
|
|
349
|
+
"string.noControlChars": "VAT registration number must not contain invalid characters"
|
|
350
|
+
})
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
// src/schemas/business/business-vat-remove-schema.js
|
|
354
|
+
var businessVatRemoveSchema = Joi.object({
|
|
355
|
+
confirmRemove: Joi.string().valid("yes", "no").required().messages({
|
|
356
|
+
"any.required": "Select yes if you want to remove your VAT registration number",
|
|
357
|
+
"any.only": "Select yes if you want to remove your VAT registration number"
|
|
358
|
+
})
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
// src/schemas/business/business-schemas.js
|
|
362
|
+
var businessSchemas = {
|
|
363
|
+
sbi: businessSbiSchema,
|
|
364
|
+
details: {
|
|
365
|
+
name: businessNameSchema,
|
|
366
|
+
address: addressSchema,
|
|
367
|
+
phone: businessPhoneSchema,
|
|
368
|
+
email: businessEmailSchema,
|
|
369
|
+
vat: businessVatSchema
|
|
370
|
+
},
|
|
371
|
+
vat: {
|
|
372
|
+
change: businessVatChangeSchema,
|
|
373
|
+
remove: businessVatRemoveSchema
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
// src/schemas/customer/customer-crn-schema.js
|
|
378
|
+
var customerCrnSchema = Joi.object({
|
|
379
|
+
crn: Joi.string().pattern(/^\d{10}$/).allow("").optional().messages({
|
|
380
|
+
"string.pattern.base": "Enter the full CRN",
|
|
381
|
+
"string.noControlChars": "CRN must not contain invalid characters"
|
|
382
|
+
})
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// src/schemas/customer/customer-schemas.js
|
|
386
|
+
var customerSchemas = {
|
|
387
|
+
crn: customerCrnSchema
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
// src/schemas/personal/personal-name-schema.js
|
|
391
|
+
var personalNameSchema = Joi.object({
|
|
392
|
+
first: Joi.string().trim().required().max(FIRST_NAME_MAX).messages({
|
|
393
|
+
"string.empty": "Enter first name",
|
|
394
|
+
"string.max": `First name must be ${FIRST_NAME_MAX} characters or less`,
|
|
395
|
+
"any.required": "Enter first name",
|
|
396
|
+
"string.noControlChars": "First name must not contain invalid characters"
|
|
397
|
+
}),
|
|
398
|
+
last: Joi.string().trim().required().max(LAST_NAME_MAX).messages({
|
|
399
|
+
"string.empty": "Enter last name",
|
|
400
|
+
"string.max": `Last name must be ${LAST_NAME_MAX} characters or less`,
|
|
401
|
+
"any.required": "Enter last name",
|
|
402
|
+
"string.noControlChars": "Last name must not contain invalid characters"
|
|
403
|
+
}),
|
|
404
|
+
middle: Joi.string().trim().allow("").max(MIDDLE_NAMES_MAX).messages({
|
|
405
|
+
"string.max": `Middle names must be ${MIDDLE_NAMES_MAX} characters or less`,
|
|
406
|
+
"string.noControlChars": "Middle names must not contain invalid characters"
|
|
407
|
+
})
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
// src/schemas/personal/personal-dob-schema.js
|
|
411
|
+
var personalDobSchema = Joi.object({
|
|
412
|
+
day: Joi.string().allow(""),
|
|
413
|
+
month: Joi.string().allow(""),
|
|
414
|
+
year: Joi.string().allow("")
|
|
415
|
+
}).custom((value, helpers) => {
|
|
416
|
+
const { day, month, year } = value;
|
|
417
|
+
const missingFieldsError = checkMissingFields(day, month, year, helpers);
|
|
418
|
+
if (missingFieldsError) {
|
|
419
|
+
return missingFieldsError;
|
|
420
|
+
}
|
|
421
|
+
if (year && year.length !== 4) {
|
|
422
|
+
return makeError(helpers, "dob.yearLength", ["year"]);
|
|
423
|
+
}
|
|
424
|
+
const monthValue = getMonthNumber(month, helpers);
|
|
425
|
+
if (monthValue.isJoiError) {
|
|
426
|
+
return monthValue;
|
|
427
|
+
}
|
|
428
|
+
const fullDate = getFullDate(day, monthValue, year, helpers);
|
|
429
|
+
if (fullDate.isJoiError) {
|
|
430
|
+
return fullDate;
|
|
431
|
+
}
|
|
432
|
+
const today = /* @__PURE__ */ new Date();
|
|
433
|
+
today.setUTCHours(0, 0, 0, 0);
|
|
434
|
+
if (fullDate >= today) {
|
|
435
|
+
return makeError(helpers, "dob.future", ["day", "month", "year"]);
|
|
436
|
+
}
|
|
437
|
+
const tooOldError = checkNotTooOld(fullDate, helpers);
|
|
438
|
+
if (tooOldError) {
|
|
439
|
+
return tooOldError;
|
|
440
|
+
}
|
|
441
|
+
return value;
|
|
442
|
+
}).messages({
|
|
443
|
+
"dob.missingAll": "Enter your date of birth",
|
|
444
|
+
"dob.missingDay": "Date of birth must include a day",
|
|
445
|
+
"dob.missingMonth": "Date of birth must include a month",
|
|
446
|
+
"dob.missingYear": "Date of birth must include a year",
|
|
447
|
+
"dob.missingDayMonth": "Date of birth must include a day and month",
|
|
448
|
+
"dob.missingDayYear": "Date of birth must include a day and year",
|
|
449
|
+
"dob.missingMonthYear": "Date of birth must include a month and year",
|
|
450
|
+
"dob.yearLength": "Enter a year with 4 numbers, like 1975",
|
|
451
|
+
"dob.invalid": "Date of birth must be a real date",
|
|
452
|
+
"dob.future": "Date of birth must be in the past",
|
|
453
|
+
"dob.tooOld": "Date of birth must be on or after {{#oldest}}",
|
|
454
|
+
"string.noControlChars": "Date of birth must not contain invalid characters"
|
|
455
|
+
});
|
|
456
|
+
var checkNotTooOld = (fullDate, helpers) => {
|
|
457
|
+
const oldestDateAllowed = getOldestAllowedDate();
|
|
458
|
+
if (fullDate < oldestDateAllowed) {
|
|
459
|
+
const oldestDateString = oldestDateAllowed.toLocaleDateString("en-GB", {
|
|
460
|
+
day: "numeric",
|
|
461
|
+
month: "long",
|
|
462
|
+
year: "numeric"
|
|
463
|
+
});
|
|
464
|
+
const error = helpers.error("dob.tooOld", { oldest: oldestDateString });
|
|
465
|
+
error.path = ["day", "month", "year"];
|
|
466
|
+
return error;
|
|
467
|
+
}
|
|
468
|
+
return null;
|
|
469
|
+
};
|
|
470
|
+
var getOldestAllowedDate = () => {
|
|
471
|
+
const date = /* @__PURE__ */ new Date();
|
|
472
|
+
date.setUTCHours(0, 0, 0, 0);
|
|
473
|
+
date.setUTCFullYear(date.getUTCFullYear() - MAX_AGE_YEARS);
|
|
474
|
+
return date;
|
|
475
|
+
};
|
|
476
|
+
var getFullDate = (day, monthValue, year, helpers) => {
|
|
477
|
+
const dayValue = Number.parseInt(day, 10);
|
|
478
|
+
const yearValue = Number.parseInt(year, 10);
|
|
479
|
+
const date = new Date(Date.UTC(yearValue, monthValue - 1, dayValue));
|
|
480
|
+
if (date.getUTCFullYear() !== yearValue || date.getUTCMonth() + 1 !== monthValue || date.getUTCDate() !== dayValue) {
|
|
481
|
+
return makeError(helpers, "dob.invalid", ["day", "month", "year"]);
|
|
482
|
+
}
|
|
483
|
+
return date;
|
|
484
|
+
};
|
|
485
|
+
var getMonthNumber = (month, helpers) => {
|
|
486
|
+
if (Number.isNaN(Number(month))) {
|
|
487
|
+
const lower = month.toLowerCase();
|
|
488
|
+
const mapped = MONTH_MAP[lower];
|
|
489
|
+
if (!mapped) {
|
|
490
|
+
return makeError(helpers, "dob.invalid", ["month"]);
|
|
491
|
+
}
|
|
492
|
+
return mapped;
|
|
493
|
+
}
|
|
494
|
+
const parsedMonth = Number.parseInt(month, 10);
|
|
495
|
+
if (parsedMonth < 1 || parsedMonth > 12) {
|
|
496
|
+
return makeError(helpers, "dob.invalid", ["month"]);
|
|
497
|
+
}
|
|
498
|
+
return parsedMonth;
|
|
499
|
+
};
|
|
500
|
+
var checkMissingFields = (day, month, year, helpers) => {
|
|
501
|
+
if (!day && !month && !year) {
|
|
502
|
+
return makeError(helpers, "dob.missingAll", ["day", "month", "year"]);
|
|
503
|
+
}
|
|
504
|
+
if (!day && month && year) {
|
|
505
|
+
return makeError(helpers, "dob.missingDay", ["day"]);
|
|
506
|
+
}
|
|
507
|
+
if (day && !month && year) {
|
|
508
|
+
return makeError(helpers, "dob.missingMonth", ["month"]);
|
|
509
|
+
}
|
|
510
|
+
if (day && month && !year) {
|
|
511
|
+
return makeError(helpers, "dob.missingYear", ["year"]);
|
|
512
|
+
}
|
|
513
|
+
if (!day && !month && year) {
|
|
514
|
+
return makeError(helpers, "dob.missingDayMonth", ["day", "month"]);
|
|
515
|
+
}
|
|
516
|
+
if (!day && month && !year) {
|
|
517
|
+
return makeError(helpers, "dob.missingDayYear", ["day", "year"]);
|
|
518
|
+
}
|
|
519
|
+
if (day && !month && !year) {
|
|
520
|
+
return makeError(helpers, "dob.missingMonthYear", ["month", "year"]);
|
|
521
|
+
}
|
|
522
|
+
return null;
|
|
523
|
+
};
|
|
524
|
+
var makeError = (helpers, code, fields) => {
|
|
525
|
+
const error = helpers.error(code);
|
|
526
|
+
error.path = fields;
|
|
527
|
+
error.isJoiError = true;
|
|
528
|
+
return error;
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
// src/schemas/personal/personal-email-schema.js
|
|
532
|
+
var personalEmailSchema = Joi.object({
|
|
533
|
+
personalEmail: Joi.string().required().max(EMAIL_MAX).email({
|
|
636
534
|
minDomainSegments: 2,
|
|
637
535
|
tlds: {
|
|
638
|
-
allow: true
|
|
536
|
+
allow: true,
|
|
537
|
+
min: 2
|
|
639
538
|
}
|
|
640
539
|
}).messages({
|
|
641
|
-
"string.max": `
|
|
642
|
-
"string.empty": "Enter
|
|
540
|
+
"string.max": `Email address must be ${EMAIL_MAX} characters or less`,
|
|
541
|
+
"string.empty": "Enter a personal email address",
|
|
643
542
|
"string.email": "Enter an email address, like name@example.com",
|
|
644
|
-
"string.noControlChars": "
|
|
543
|
+
"string.noControlChars": "Personal email address must not contain invalid characters"
|
|
645
544
|
})
|
|
646
545
|
});
|
|
647
546
|
|
|
648
|
-
// src/schemas/
|
|
649
|
-
var
|
|
650
|
-
|
|
651
|
-
"string.min": `
|
|
652
|
-
"string.max": `
|
|
653
|
-
"string.pattern.base": "
|
|
654
|
-
"string.noControlChars": "
|
|
547
|
+
// src/schemas/personal/personal-phone-schema.js
|
|
548
|
+
var personalPhoneSchema = Joi.object({
|
|
549
|
+
personalTelephone: Joi.string().trim().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
550
|
+
"string.min": `Personal telephone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
551
|
+
"string.max": `Personal telephone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
552
|
+
"string.pattern.base": "Personal telephone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +",
|
|
553
|
+
"string.noControlChars": "Personal telephone number must not contain invalid characters"
|
|
655
554
|
}),
|
|
656
|
-
|
|
657
|
-
"string.min": `
|
|
658
|
-
"string.max": `
|
|
659
|
-
"string.pattern.base": "
|
|
660
|
-
"string.noControlChars": "
|
|
555
|
+
personalMobile: Joi.string().trim().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
556
|
+
"string.min": `Personal mobile phone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
557
|
+
"string.max": `Personal mobile phone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
558
|
+
"string.pattern.base": "Personal mobile phone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +",
|
|
559
|
+
"string.noControlChars": "Personal mobile phone number must not contain invalid characters"
|
|
661
560
|
})
|
|
662
|
-
}).or("
|
|
561
|
+
}).or("personalTelephone", "personalMobile").messages({
|
|
663
562
|
"object.missing": "Enter at least one phone number"
|
|
664
563
|
});
|
|
665
564
|
|
|
666
|
-
// src/schemas/
|
|
667
|
-
var
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
565
|
+
// src/schemas/personal/personal-schemas.js
|
|
566
|
+
var personalSchemas = {
|
|
567
|
+
name: personalNameSchema,
|
|
568
|
+
dob: personalDobSchema,
|
|
569
|
+
address: addressSchema,
|
|
570
|
+
phone: personalPhoneSchema,
|
|
571
|
+
email: personalEmailSchema
|
|
572
|
+
};
|
|
673
573
|
|
|
674
|
-
// src/schemas/
|
|
675
|
-
var
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
574
|
+
// src/schemas/os-places/address-lookup-schema.js
|
|
575
|
+
var addressLookupSchema = Joi.object({
|
|
576
|
+
properties: Joi.object({
|
|
577
|
+
UPRN: Joi.string().required(),
|
|
578
|
+
ADDRESS: Joi.string().required(),
|
|
579
|
+
ORGANISATION_NAME: Joi.string().allow(null),
|
|
580
|
+
DEPARTMENT_NAME: Joi.string().allow(null),
|
|
581
|
+
SUB_BUILDING_NAME: Joi.string().allow(null),
|
|
582
|
+
BUILDING_NAME: Joi.string().allow(null),
|
|
583
|
+
BUILDING_NUMBER: Joi.string().allow(null),
|
|
584
|
+
DEPENDENT_THOROUGHFARE_NAME: Joi.string().allow(null),
|
|
585
|
+
THOROUGHFARE_NAME: Joi.string().allow(null),
|
|
586
|
+
DOUBLE_DEPENDENT_LOCALITY: Joi.string().allow(null),
|
|
587
|
+
DEPENDENT_LOCALITY: Joi.string().allow(null),
|
|
588
|
+
POST_TOWN: Joi.string().required(),
|
|
589
|
+
POSTCODE: Joi.string().required(),
|
|
590
|
+
LOCAL_CUSTODIAN_CODE_DESCRIPTION: Joi.string().allow(null),
|
|
591
|
+
COUNTRY_CODE: Joi.string().required()
|
|
592
|
+
}).unknown(true).required()
|
|
593
|
+
}).unknown(true);
|
|
594
|
+
|
|
595
|
+
// src/schemas/os-places/addresses-schema.js
|
|
596
|
+
var CHOOSE_ADDRESS_ERROR = "Choose an address";
|
|
597
|
+
var addressesSchema = Joi.object({
|
|
598
|
+
addresses: Joi.string().invalid("display").required().messages({
|
|
599
|
+
"any.required": CHOOSE_ADDRESS_ERROR,
|
|
600
|
+
"string.empty": CHOOSE_ADDRESS_ERROR,
|
|
601
|
+
"any.invalid": CHOOSE_ADDRESS_ERROR
|
|
681
602
|
})
|
|
682
603
|
});
|
|
683
604
|
|
|
684
|
-
// src/schemas/
|
|
685
|
-
var
|
|
686
|
-
|
|
687
|
-
"any.required": "
|
|
688
|
-
"
|
|
605
|
+
// src/schemas/os-places/uk-postcode-schema.js
|
|
606
|
+
var ukPostcodeSchema = Joi.object({
|
|
607
|
+
postcode: Joi.string().trim().required().uppercase().max(POSTCODE_MAX).pattern(/^([A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}|GIR ?0A{2})$/).messages({
|
|
608
|
+
"any.required": "Enter a postcode",
|
|
609
|
+
"string.empty": "Enter a postcode",
|
|
610
|
+
"string.max": `Postal code must be ${POSTCODE_MAX} characters or less`,
|
|
611
|
+
"string.pattern.base": "Enter a full UK postcode, like AA3 1AB"
|
|
689
612
|
})
|
|
690
613
|
});
|
|
691
614
|
|
|
692
|
-
// src/schemas/
|
|
693
|
-
var
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
615
|
+
// src/schemas/os-places/os-places-schemas.js
|
|
616
|
+
var osPlacesSchemas = {
|
|
617
|
+
addressLookup: addressLookupSchema,
|
|
618
|
+
addresses: addressesSchema,
|
|
619
|
+
ukPostcode: ukPostcodeSchema
|
|
620
|
+
};
|
|
621
|
+
|
|
622
|
+
// src/schemas/schemas.js
|
|
623
|
+
var schemas = {
|
|
624
|
+
business: businessSchemas,
|
|
625
|
+
customer: customerSchemas,
|
|
626
|
+
personal: personalSchemas,
|
|
627
|
+
osPlaces: osPlacesSchemas
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
// src/constants/country-names.js
|
|
631
|
+
var COUNTRY_NAMES = {
|
|
632
|
+
E: "ENGLAND",
|
|
633
|
+
W: "WALES",
|
|
634
|
+
S: "SCOTLAND",
|
|
635
|
+
N: "NORTHERN IRELAND",
|
|
636
|
+
L: "CHANNEL ISLANDS",
|
|
637
|
+
M: "ISLE OF MAN"
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
// src/mappers/address-lookup-mapper.js
|
|
641
|
+
var addressLookupMapper = (addresses) => {
|
|
642
|
+
if (!Array.isArray(addresses)) {
|
|
643
|
+
return [];
|
|
644
|
+
}
|
|
645
|
+
return addresses.map((address) => {
|
|
646
|
+
const { error } = schemas.osPlaces.addressLookup.validate(address);
|
|
647
|
+
if (error) {
|
|
648
|
+
return null;
|
|
649
|
+
}
|
|
650
|
+
const {
|
|
651
|
+
UPRN,
|
|
652
|
+
ADDRESS,
|
|
653
|
+
PO_BOX_NUMBER,
|
|
654
|
+
ORGANISATION_NAME,
|
|
655
|
+
DEPARTMENT_NAME,
|
|
656
|
+
SUB_BUILDING_NAME,
|
|
657
|
+
BUILDING_NAME,
|
|
658
|
+
BUILDING_NUMBER,
|
|
659
|
+
DEPENDENT_THOROUGHFARE_NAME,
|
|
660
|
+
THOROUGHFARE_NAME,
|
|
661
|
+
DOUBLE_DEPENDENT_LOCALITY,
|
|
662
|
+
DEPENDENT_LOCALITY,
|
|
663
|
+
POST_TOWN,
|
|
664
|
+
POSTCODE,
|
|
665
|
+
LOCAL_CUSTODIAN_CODE_DESCRIPTION,
|
|
666
|
+
COUNTRY_CODE
|
|
667
|
+
} = address.properties;
|
|
668
|
+
const buildingName = PO_BOX_NUMBER ? `PO BOX ${PO_BOX_NUMBER}` : BUILDING_NAME || null;
|
|
669
|
+
return {
|
|
670
|
+
displayAddress: ADDRESS,
|
|
671
|
+
pafOrganisationName: filterAndJoin([ORGANISATION_NAME, DEPARTMENT_NAME]),
|
|
672
|
+
flatName: SUB_BUILDING_NAME ?? null,
|
|
673
|
+
buildingName,
|
|
674
|
+
buildingNumberRange: BUILDING_NUMBER ?? null,
|
|
675
|
+
street: filterAndJoin([DEPENDENT_THOROUGHFARE_NAME, THOROUGHFARE_NAME]),
|
|
676
|
+
dependentLocality: DEPENDENT_LOCALITY ?? null,
|
|
677
|
+
doubleDependentLocality: DOUBLE_DEPENDENT_LOCALITY ?? null,
|
|
678
|
+
city: POST_TOWN,
|
|
679
|
+
county: formatCounty(LOCAL_CUSTODIAN_CODE_DESCRIPTION, POST_TOWN),
|
|
680
|
+
postcode: POSTCODE,
|
|
681
|
+
country: COUNTRY_NAMES[COUNTRY_CODE] ?? null,
|
|
682
|
+
uprn: UPRN
|
|
683
|
+
};
|
|
684
|
+
}).filter(Boolean);
|
|
685
|
+
};
|
|
686
|
+
var formatCounty = (localCustodianCodeDescription, postTown) => {
|
|
687
|
+
if (localCustodianCodeDescription === "ORDNANCE SURVEY" || localCustodianCodeDescription === postTown) {
|
|
688
|
+
return null;
|
|
689
|
+
}
|
|
690
|
+
return localCustodianCodeDescription;
|
|
691
|
+
};
|
|
692
|
+
var filterAndJoin = (addressesProperties) => {
|
|
693
|
+
return addressesProperties.filter(Boolean).join(", ") || null;
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
// src/mappers/mappers.js
|
|
697
|
+
var mappers = {
|
|
698
|
+
personalBusinessDetails: mapPersonalBusinessDetails,
|
|
699
|
+
address: mapAddress,
|
|
700
|
+
customerName: mapCustomerName,
|
|
701
|
+
businessDetails: mapBusinessDetails,
|
|
702
|
+
addressLookup: addressLookupMapper
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
// src/mutations/business/update-business-email.js
|
|
706
|
+
var updateBusinessEmailMutation = `
|
|
707
|
+
mutation Mutation($input: UpdateBusinessEmailInput!) {
|
|
708
|
+
updateBusinessEmail(input: $input) {
|
|
709
|
+
business {
|
|
710
|
+
info {
|
|
711
|
+
email {
|
|
712
|
+
address
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
success
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
`;
|
|
720
|
+
|
|
721
|
+
// src/mutations/business/update-business-name.js
|
|
722
|
+
var updateBusinessNameMutation = `
|
|
723
|
+
mutation UpdateBusinessName($input: UpdateBusinessNameInput!) {
|
|
724
|
+
updateBusinessName(input: $input) {
|
|
725
|
+
business {
|
|
726
|
+
info {
|
|
727
|
+
name
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
success
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
`;
|
|
734
|
+
|
|
735
|
+
// src/mutations/personal/update-customer-name.js
|
|
736
|
+
var updateCustomerNameMutation = `
|
|
737
|
+
mutation UpdateCustomerName($input: UpdateCustomerNameInput!) {
|
|
738
|
+
updateCustomerName(input: $input) {
|
|
739
|
+
customer {
|
|
740
|
+
info {
|
|
741
|
+
name {
|
|
742
|
+
first
|
|
743
|
+
last
|
|
744
|
+
middle
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
`;
|
|
751
|
+
|
|
752
|
+
// src/mutations/personal/update-customer-dob.js
|
|
753
|
+
var updateCustomerDobMutation = `
|
|
754
|
+
mutation UpdateCustomerDateOfBirth($input: UpdateCustomerDateOfBirthInput!) {
|
|
755
|
+
updateCustomerDateOfBirth(input: $input) {
|
|
756
|
+
customer {
|
|
757
|
+
info {
|
|
758
|
+
dateOfBirth
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
`;
|
|
764
|
+
|
|
765
|
+
// src/mutations/personal/update-customer-phone.js
|
|
766
|
+
var updateCustomerPhoneMutation = `
|
|
767
|
+
mutation UpdateCustomerPhone($input: UpdateCustomerPhoneInput!) {
|
|
768
|
+
updateCustomerPhone(input: $input) {
|
|
769
|
+
customer {
|
|
770
|
+
info {
|
|
771
|
+
phone {
|
|
772
|
+
landline
|
|
773
|
+
mobile
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
}
|
|
705
778
|
}
|
|
706
|
-
|
|
779
|
+
`;
|
|
707
780
|
|
|
708
|
-
// src/
|
|
709
|
-
var
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
781
|
+
// src/mutations/personal/update-customer-email.js
|
|
782
|
+
var updateCustomerEmailMutation = `
|
|
783
|
+
mutation UpdateCustomerEmail($input: UpdateCustomerEmailInput!) {
|
|
784
|
+
updateCustomerEmail(input: $input) {
|
|
785
|
+
customer {
|
|
786
|
+
info {
|
|
787
|
+
email {
|
|
788
|
+
address
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
`;
|
|
715
795
|
|
|
716
|
-
// src/
|
|
717
|
-
var
|
|
718
|
-
|
|
796
|
+
// src/mutations/mutations.js
|
|
797
|
+
var mutations = {
|
|
798
|
+
updateBusinessEmail: updateBusinessEmailMutation,
|
|
799
|
+
updateBusinessName: updateBusinessNameMutation,
|
|
800
|
+
updateCustomerName: updateCustomerNameMutation,
|
|
801
|
+
updateCustomerDob: updateCustomerDobMutation,
|
|
802
|
+
updateCustomerPhone: updateCustomerPhoneMutation,
|
|
803
|
+
updateCustomerEmail: updateCustomerEmailMutation
|
|
719
804
|
};
|
|
720
805
|
|
|
721
|
-
// src/
|
|
722
|
-
var
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
"any.required": "Enter first name",
|
|
727
|
-
"string.noControlChars": "First name must not contain invalid characters"
|
|
728
|
-
}),
|
|
729
|
-
last: Joi.string().trim().required().max(LAST_NAME_MAX).messages({
|
|
730
|
-
"string.empty": "Enter last name",
|
|
731
|
-
"string.max": `Last name must be ${LAST_NAME_MAX} characters or less`,
|
|
732
|
-
"any.required": "Enter last name",
|
|
733
|
-
"string.noControlChars": "Last name must not contain invalid characters"
|
|
734
|
-
}),
|
|
735
|
-
middle: Joi.string().trim().allow("").max(MIDDLE_NAMES_MAX).messages({
|
|
736
|
-
"string.max": `Middle names must be ${MIDDLE_NAMES_MAX} characters or less`,
|
|
737
|
-
"string.noControlChars": "Middle names must not contain invalid characters"
|
|
738
|
-
})
|
|
739
|
-
});
|
|
740
|
-
|
|
741
|
-
// src/schemas/personal/personal-dob-schema.js
|
|
742
|
-
var personalDobSchema = Joi.object({
|
|
743
|
-
day: Joi.string().allow(""),
|
|
744
|
-
month: Joi.string().allow(""),
|
|
745
|
-
year: Joi.string().allow("")
|
|
746
|
-
}).custom((value, helpers) => {
|
|
747
|
-
const { day, month, year } = value;
|
|
748
|
-
const missingFieldsError = checkMissingFields(day, month, year, helpers);
|
|
749
|
-
if (missingFieldsError) {
|
|
750
|
-
return missingFieldsError;
|
|
806
|
+
// src/presenters/base-presenter.js
|
|
807
|
+
var BACK_LINK_DISPLAY_MAX = 50;
|
|
808
|
+
var formatBackLink = (businessName) => {
|
|
809
|
+
if (businessName.length > BACK_LINK_DISPLAY_MAX) {
|
|
810
|
+
return `Back to ${businessName.slice(0, BACK_LINK_DISPLAY_MAX)}\u2026`;
|
|
751
811
|
}
|
|
752
|
-
|
|
753
|
-
|
|
812
|
+
return `Back to ${businessName}`;
|
|
813
|
+
};
|
|
814
|
+
var formatNumber = (payloadNumber, changedNumber, originalNumber) => {
|
|
815
|
+
if (payloadNumber !== void 0) {
|
|
816
|
+
return payloadNumber;
|
|
754
817
|
}
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
return monthValue;
|
|
818
|
+
if (changedNumber !== void 0) {
|
|
819
|
+
return changedNumber;
|
|
758
820
|
}
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
821
|
+
return originalNumber;
|
|
822
|
+
};
|
|
823
|
+
var formatDatePart = (changed, original) => {
|
|
824
|
+
return changed ?? (original == null ? void 0 : original.toString()) ?? "";
|
|
825
|
+
};
|
|
826
|
+
var formatDateInputValues = (payloadDob, changedDob, originalDob) => {
|
|
827
|
+
if (payloadDob) {
|
|
828
|
+
return {
|
|
829
|
+
day: payloadDob.day ?? "",
|
|
830
|
+
month: payloadDob.month ?? "",
|
|
831
|
+
year: payloadDob.year ?? ""
|
|
832
|
+
};
|
|
762
833
|
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
834
|
+
return {
|
|
835
|
+
day: formatDatePart(changedDob == null ? void 0 : changedDob.day, originalDob == null ? void 0 : originalDob.day),
|
|
836
|
+
month: formatDatePart(changedDob == null ? void 0 : changedDob.month, originalDob == null ? void 0 : originalDob.month),
|
|
837
|
+
year: formatDatePart(changedDob == null ? void 0 : changedDob.year, originalDob == null ? void 0 : originalDob.year)
|
|
838
|
+
};
|
|
839
|
+
};
|
|
840
|
+
var sortErrorsBySectionOrder = (errors, orderedSectionsToFix, SECTION_FIELD_ORDER) => {
|
|
841
|
+
const sortedErrors = [];
|
|
842
|
+
for (const section of orderedSectionsToFix) {
|
|
843
|
+
const fieldsInSection = SECTION_FIELD_ORDER[section] || [];
|
|
844
|
+
for (const field of fieldsInSection) {
|
|
845
|
+
if (errors[field]) {
|
|
846
|
+
sortedErrors.push({
|
|
847
|
+
field,
|
|
848
|
+
...errors[field]
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
}
|
|
767
852
|
}
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
853
|
+
return sortedErrors;
|
|
854
|
+
};
|
|
855
|
+
|
|
856
|
+
// src/presenters/address-presenter.js
|
|
857
|
+
var addressChangeLink = (postcodeLookup, context) => {
|
|
858
|
+
if (context === "business") {
|
|
859
|
+
if (postcodeLookup) {
|
|
860
|
+
return "/business-address-change";
|
|
861
|
+
}
|
|
862
|
+
return "/business-address-enter";
|
|
771
863
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
"dob.missingYear": "Date of birth must include a year",
|
|
778
|
-
"dob.missingDayMonth": "Date of birth must include a day and month",
|
|
779
|
-
"dob.missingDayYear": "Date of birth must include a day and year",
|
|
780
|
-
"dob.missingMonthYear": "Date of birth must include a month and year",
|
|
781
|
-
"dob.yearLength": "Enter a year with 4 numbers, like 1975",
|
|
782
|
-
"dob.invalid": "Date of birth must be a real date",
|
|
783
|
-
"dob.future": "Date of birth must be in the past",
|
|
784
|
-
"dob.tooOld": "Date of birth must be on or after {{#oldest}}",
|
|
785
|
-
"string.noControlChars": "Date of birth must not contain invalid characters"
|
|
786
|
-
});
|
|
787
|
-
var checkNotTooOld = (fullDate, helpers) => {
|
|
788
|
-
const oldestDateAllowed = getOldestAllowedDate();
|
|
789
|
-
if (fullDate < oldestDateAllowed) {
|
|
790
|
-
const oldestDateString = oldestDateAllowed.toLocaleDateString("en-GB", {
|
|
791
|
-
day: "numeric",
|
|
792
|
-
month: "long",
|
|
793
|
-
year: "numeric"
|
|
794
|
-
});
|
|
795
|
-
const error = helpers.error("dob.tooOld", { oldest: oldestDateString });
|
|
796
|
-
error.path = ["day", "month", "year"];
|
|
797
|
-
return error;
|
|
864
|
+
if (context === "personal") {
|
|
865
|
+
if (postcodeLookup) {
|
|
866
|
+
return "/account-address-change";
|
|
867
|
+
}
|
|
868
|
+
return "/account-address-enter";
|
|
798
869
|
}
|
|
799
870
|
return null;
|
|
800
871
|
};
|
|
801
|
-
var
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
};
|
|
807
|
-
var getFullDate = (day, monthValue, year, helpers) => {
|
|
808
|
-
const dayValue = Number.parseInt(day, 10);
|
|
809
|
-
const yearValue = Number.parseInt(year, 10);
|
|
810
|
-
const date = new Date(Date.UTC(yearValue, monthValue - 1, dayValue));
|
|
811
|
-
if (date.getUTCFullYear() !== yearValue || date.getUTCMonth() + 1 !== monthValue || date.getUTCDate() !== dayValue) {
|
|
812
|
-
return makeError(helpers, "dob.invalid", ["day", "month", "year"]);
|
|
872
|
+
var addressBackLink = (postcodeLookup, context) => {
|
|
873
|
+
if (context === "business") {
|
|
874
|
+
if (postcodeLookup) {
|
|
875
|
+
return { href: "/business-address-select" };
|
|
876
|
+
}
|
|
877
|
+
return { href: "/business-address-enter" };
|
|
813
878
|
}
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
if (Number.isNaN(Number(month))) {
|
|
818
|
-
const lower = month.toLowerCase();
|
|
819
|
-
const mapped = MONTH_MAP[lower];
|
|
820
|
-
if (!mapped) {
|
|
821
|
-
return makeError(helpers, "dob.invalid", ["month"]);
|
|
879
|
+
if (context === "personal") {
|
|
880
|
+
if (postcodeLookup) {
|
|
881
|
+
return { href: "/account-address-select" };
|
|
822
882
|
}
|
|
823
|
-
return
|
|
883
|
+
return { href: "/account-address-enter" };
|
|
824
884
|
}
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
885
|
+
return null;
|
|
886
|
+
};
|
|
887
|
+
var buildAddressLine = (parts) => {
|
|
888
|
+
return parts.filter(Boolean).join(", ") || null;
|
|
889
|
+
};
|
|
890
|
+
var buildStreetLine = (buildingRange, street) => {
|
|
891
|
+
return [buildingRange, street].filter(Boolean).join(" ") || null;
|
|
892
|
+
};
|
|
893
|
+
var formatLookupAddress = (lookup, city, country, postcode) => ({
|
|
894
|
+
address1: buildAddressLine([lookup.pafOrganisationName, lookup.flatName, lookup.buildingName]),
|
|
895
|
+
address2: buildStreetLine(lookup.buildingNumberRange, lookup.street),
|
|
896
|
+
address3: buildAddressLine([lookup.doubleDependentLocality, lookup.dependentLocality]),
|
|
897
|
+
county: lookup.county ?? null,
|
|
898
|
+
city: city ?? null,
|
|
899
|
+
country: country ?? null,
|
|
900
|
+
postcode: postcode ?? null
|
|
901
|
+
});
|
|
902
|
+
var formatManualAddress = (manual, city, country, postcode) => ({
|
|
903
|
+
address1: manual.line1 ?? null,
|
|
904
|
+
address2: manual.line2 ?? null,
|
|
905
|
+
address3: manual.line3 ?? null,
|
|
906
|
+
city: city ?? null,
|
|
907
|
+
county: manual.line4 ?? null,
|
|
908
|
+
country: country ?? null,
|
|
909
|
+
postcode: postcode ?? null
|
|
910
|
+
});
|
|
911
|
+
var formatDisplayAddress = (address) => {
|
|
912
|
+
const { lookup, manual, postcode, country, city } = address;
|
|
913
|
+
let addressLines = [];
|
|
914
|
+
if (lookup.uprn) {
|
|
915
|
+
const buildingAndStreet = [
|
|
916
|
+
lookup.buildingNumberRange,
|
|
917
|
+
lookup.street
|
|
918
|
+
].filter(Boolean).join(" ");
|
|
919
|
+
addressLines = [
|
|
920
|
+
lookup.pafOrganisationName,
|
|
921
|
+
lookup.flatName,
|
|
922
|
+
lookup.buildingName,
|
|
923
|
+
buildingAndStreet,
|
|
924
|
+
lookup.doubleDependentLocality,
|
|
925
|
+
lookup.dependentLocality,
|
|
926
|
+
city,
|
|
927
|
+
lookup.county
|
|
928
|
+
];
|
|
929
|
+
} else {
|
|
930
|
+
addressLines = [
|
|
931
|
+
manual.line1,
|
|
932
|
+
manual.line2,
|
|
933
|
+
manual.line3,
|
|
934
|
+
city,
|
|
935
|
+
manual.line4,
|
|
936
|
+
// County
|
|
937
|
+
manual.line5
|
|
938
|
+
];
|
|
828
939
|
}
|
|
829
|
-
return
|
|
940
|
+
return [
|
|
941
|
+
...addressLines.filter(Boolean),
|
|
942
|
+
postcode,
|
|
943
|
+
country
|
|
944
|
+
];
|
|
830
945
|
};
|
|
831
|
-
var
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
if (day && !month && year) {
|
|
839
|
-
return makeError(helpers, "dob.missingMonth", ["month"]);
|
|
840
|
-
}
|
|
841
|
-
if (day && month && !year) {
|
|
842
|
-
return makeError(helpers, "dob.missingYear", ["year"]);
|
|
843
|
-
}
|
|
844
|
-
if (!day && !month && year) {
|
|
845
|
-
return makeError(helpers, "dob.missingDayMonth", ["day", "month"]);
|
|
846
|
-
}
|
|
847
|
-
if (!day && month && !year) {
|
|
848
|
-
return makeError(helpers, "dob.missingDayYear", ["day", "year"]);
|
|
849
|
-
}
|
|
850
|
-
if (day && !month && !year) {
|
|
851
|
-
return makeError(helpers, "dob.missingMonthYear", ["month", "year"]);
|
|
946
|
+
var formatOriginalAddress = (originalAddress) => {
|
|
947
|
+
const { lookup, manual, city, country, postcode } = originalAddress;
|
|
948
|
+
return lookup.uprn ? formatLookupAddress(lookup, city, country, postcode) : formatManualAddress(manual, city, country, postcode);
|
|
949
|
+
};
|
|
950
|
+
var formatChangedAddress = (changeBusinessAddress) => {
|
|
951
|
+
if (!changeBusinessAddress.uprn) {
|
|
952
|
+
return changeBusinessAddress;
|
|
852
953
|
}
|
|
853
|
-
|
|
954
|
+
const {
|
|
955
|
+
pafOrganisationName,
|
|
956
|
+
flatName,
|
|
957
|
+
buildingName,
|
|
958
|
+
buildingNumberRange,
|
|
959
|
+
street,
|
|
960
|
+
doubleDependentLocality,
|
|
961
|
+
dependentLocality,
|
|
962
|
+
city,
|
|
963
|
+
county,
|
|
964
|
+
country,
|
|
965
|
+
postcode
|
|
966
|
+
} = changeBusinessAddress;
|
|
967
|
+
return {
|
|
968
|
+
address1: buildAddressLine([pafOrganisationName, flatName, buildingName]),
|
|
969
|
+
address2: buildStreetLine(buildingNumberRange, street),
|
|
970
|
+
address3: buildAddressLine([doubleDependentLocality, dependentLocality]),
|
|
971
|
+
city: city ?? null,
|
|
972
|
+
county: county ?? null,
|
|
973
|
+
country: country ?? null,
|
|
974
|
+
postcode: postcode ?? null
|
|
975
|
+
};
|
|
854
976
|
};
|
|
855
|
-
var
|
|
856
|
-
const
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
977
|
+
var formatDisplayAddresses = (addresses, previouslyPickedAddress) => {
|
|
978
|
+
const displayAddresses = addresses.map((address) => ({
|
|
979
|
+
value: `${address.uprn}${address.displayAddress}`,
|
|
980
|
+
text: address.displayAddress,
|
|
981
|
+
selected: (previouslyPickedAddress == null ? void 0 : previouslyPickedAddress.uprn) === address.uprn && (previouslyPickedAddress == null ? void 0 : previouslyPickedAddress.displayAddress) === address.displayAddress
|
|
982
|
+
}));
|
|
983
|
+
const hasSelectedAddress = displayAddresses.some((addr) => addr.selected);
|
|
984
|
+
const text = addresses.length === 1 ? "1 address found" : `${addresses.length} addresses found`;
|
|
985
|
+
displayAddresses.unshift({
|
|
986
|
+
value: "display",
|
|
987
|
+
text,
|
|
988
|
+
selected: !hasSelectedAddress
|
|
989
|
+
});
|
|
990
|
+
return displayAddresses;
|
|
860
991
|
};
|
|
861
992
|
|
|
862
|
-
// src/
|
|
863
|
-
var
|
|
864
|
-
|
|
865
|
-
minDomainSegments: 2,
|
|
866
|
-
tlds: {
|
|
867
|
-
allow: true,
|
|
868
|
-
min: 2
|
|
869
|
-
}
|
|
870
|
-
}).messages({
|
|
871
|
-
"string.max": `Email address must be ${EMAIL_MAX} characters or less`,
|
|
872
|
-
"string.empty": "Enter a personal email address",
|
|
873
|
-
"string.email": "Enter an email address, like name@example.com",
|
|
874
|
-
"string.noControlChars": "Personal email address must not contain invalid characters"
|
|
875
|
-
})
|
|
876
|
-
});
|
|
877
|
-
|
|
878
|
-
// src/schemas/personal/personal-phone-schema.js
|
|
879
|
-
var personalPhoneSchema = Joi.object({
|
|
880
|
-
personalTelephone: Joi.string().trim().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
881
|
-
"string.min": `Personal telephone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
882
|
-
"string.max": `Personal telephone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
883
|
-
"string.pattern.base": "Personal telephone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +",
|
|
884
|
-
"string.noControlChars": "Personal telephone number must not contain invalid characters"
|
|
885
|
-
}),
|
|
886
|
-
personalMobile: Joi.string().trim().empty("").min(PHONE_NUMBER_MIN).max(PHONE_NUMBER_MAX).pattern(PHONE_NUMBER_PATTERN).messages({
|
|
887
|
-
"string.min": `Personal mobile phone number must be ${PHONE_NUMBER_MIN} characters or more`,
|
|
888
|
-
"string.max": `Personal mobile phone number must be ${PHONE_NUMBER_MAX} characters or less`,
|
|
889
|
-
"string.pattern.base": "Personal mobile phone number must only include numbers 0 to 9 and special characters such as spaces, brackets and +",
|
|
890
|
-
"string.noControlChars": "Personal mobile phone number must not contain invalid characters"
|
|
891
|
-
})
|
|
892
|
-
}).or("personalTelephone", "personalMobile").messages({
|
|
893
|
-
"object.missing": "Enter at least one phone number"
|
|
894
|
-
});
|
|
895
|
-
|
|
896
|
-
// src/schemas/personal/personal-schemas.js
|
|
897
|
-
var personalSchemas = {
|
|
898
|
-
name: personalNameSchema,
|
|
899
|
-
dob: personalDobSchema,
|
|
900
|
-
address: addressSchema,
|
|
901
|
-
phone: personalPhoneSchema,
|
|
902
|
-
email: personalEmailSchema
|
|
993
|
+
// src/presenters/business-details-presenter.js
|
|
994
|
+
var getActionText = (value) => {
|
|
995
|
+
return value ? "Change" : "Add";
|
|
903
996
|
};
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
THOROUGHFARE_NAME: Joi.string().allow(null),
|
|
917
|
-
DOUBLE_DEPENDENT_LOCALITY: Joi.string().allow(null),
|
|
918
|
-
DEPENDENT_LOCALITY: Joi.string().allow(null),
|
|
919
|
-
POST_TOWN: Joi.string().required(),
|
|
920
|
-
POSTCODE: Joi.string().required(),
|
|
921
|
-
LOCAL_CUSTODIAN_CODE_DESCRIPTION: Joi.string().allow(null),
|
|
922
|
-
COUNTRY_CODE: Joi.string().required()
|
|
923
|
-
}).unknown(true).required()
|
|
924
|
-
}).unknown(true);
|
|
925
|
-
|
|
926
|
-
// src/schemas/os-places/addresses-schema.js
|
|
927
|
-
var CHOOSE_ADDRESS_ERROR = "Choose an address";
|
|
928
|
-
var addressesSchema = Joi.object({
|
|
929
|
-
addresses: Joi.string().invalid("display").required().messages({
|
|
930
|
-
"any.required": CHOOSE_ADDRESS_ERROR,
|
|
931
|
-
"string.empty": CHOOSE_ADDRESS_ERROR,
|
|
932
|
-
"any.invalid": CHOOSE_ADDRESS_ERROR
|
|
933
|
-
})
|
|
934
|
-
});
|
|
935
|
-
|
|
936
|
-
// src/schemas/os-places/uk-postcode-schema.js
|
|
937
|
-
var ukPostcodeSchema = Joi.object({
|
|
938
|
-
postcode: Joi.string().trim().required().uppercase().max(POSTCODE_MAX).pattern(/^([A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}|GIR ?0A{2})$/).messages({
|
|
939
|
-
"any.required": "Enter a postcode",
|
|
940
|
-
"string.empty": "Enter a postcode",
|
|
941
|
-
"string.max": `Postal code must be ${POSTCODE_MAX} characters or less`,
|
|
942
|
-
"string.pattern.base": "Enter a full UK postcode, like AA3 1AB"
|
|
943
|
-
})
|
|
944
|
-
});
|
|
945
|
-
|
|
946
|
-
// src/schemas/os-places/os-places-schemas.js
|
|
947
|
-
var osPlacesSchemas = {
|
|
948
|
-
addressLookup: addressLookupSchema,
|
|
949
|
-
addresses: addressesSchema,
|
|
950
|
-
ukPostcode: ukPostcodeSchema
|
|
997
|
+
var formatCph = (countyParishHoldings) => {
|
|
998
|
+
return (countyParishHoldings || []).filter((cph) => cph == null ? void 0 : cph.cphNumber).map((cph) => cph.cphNumber);
|
|
999
|
+
};
|
|
1000
|
+
var formatCphText = (count) => {
|
|
1001
|
+
return `County Parish Holding (CPH) number${count !== 1 ? "s" : ""}`;
|
|
1002
|
+
};
|
|
1003
|
+
var formatBusinessAddress = (businessAddress) => {
|
|
1004
|
+
var _a, _b;
|
|
1005
|
+
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)) {
|
|
1006
|
+
return formatDisplayAddress(businessAddress);
|
|
1007
|
+
}
|
|
1008
|
+
return [];
|
|
951
1009
|
};
|
|
952
1010
|
|
|
953
|
-
// src/
|
|
954
|
-
var
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
1011
|
+
// src/presenters/presenters.js
|
|
1012
|
+
var presenters = {
|
|
1013
|
+
formatBackLink,
|
|
1014
|
+
formatNumber,
|
|
1015
|
+
formatDateInputValues,
|
|
1016
|
+
formatDisplayAddress,
|
|
1017
|
+
formatOriginalAddress,
|
|
1018
|
+
formatChangedAddress,
|
|
1019
|
+
formatDisplayAddresses,
|
|
1020
|
+
sortErrorsBySectionOrder,
|
|
1021
|
+
getActionText,
|
|
1022
|
+
formatCph,
|
|
1023
|
+
formatCphText,
|
|
1024
|
+
formatBusinessAddress,
|
|
1025
|
+
addressBackLink,
|
|
1026
|
+
addressChangeLink
|
|
959
1027
|
};
|
|
960
1028
|
|
|
961
1029
|
// src/utils/format-full-name.js
|
|
@@ -1010,6 +1078,253 @@ var utils = {
|
|
|
1010
1078
|
buildUpdateBusinessEmailVariables,
|
|
1011
1079
|
buildUpdateBusinessNameVariables
|
|
1012
1080
|
};
|
|
1081
|
+
|
|
1082
|
+
// src/services/os-places/address-lookup-service.js
|
|
1083
|
+
var import_osdatahub = require("osdatahub");
|
|
1084
|
+
|
|
1085
|
+
// src/mock-data/mock-os-places-addresses.js
|
|
1086
|
+
var mockAddresses = [
|
|
1087
|
+
{
|
|
1088
|
+
properties: {
|
|
1089
|
+
UPRN: "10000001",
|
|
1090
|
+
ADDRESS: "APARTMENT 1, REDBRIDGE HOUSE, 1 ROSE COURT, LONDON, SW1A 1AA",
|
|
1091
|
+
SUB_BUILDING_NAME: "APARTMENT 1",
|
|
1092
|
+
BUILDING_NAME: "REDBRIDGE HOUSE",
|
|
1093
|
+
BUILDING_NUMBER: "1",
|
|
1094
|
+
THOROUGHFARE_NAME: "ROSE COURT",
|
|
1095
|
+
POST_TOWN: "LONDON",
|
|
1096
|
+
POSTCODE: "SW1A 1AA",
|
|
1097
|
+
LOCAL_CUSTODIAN_CODE_DESCRIPTION: "GREATER LONDON",
|
|
1098
|
+
COUNTRY_CODE: "E"
|
|
1099
|
+
}
|
|
1100
|
+
},
|
|
1101
|
+
{
|
|
1102
|
+
properties: {
|
|
1103
|
+
UPRN: "10000002",
|
|
1104
|
+
ADDRESS: "FLAT 2B, KINGSLEY APARTMENTS, 12 VICTORIA SQUARE, LONDON, SW1A 1AA",
|
|
1105
|
+
SUB_BUILDING_NAME: "FLAT 2B",
|
|
1106
|
+
BUILDING_NAME: "KINGSLEY APARTMENTS",
|
|
1107
|
+
BUILDING_NUMBER: "12",
|
|
1108
|
+
THOROUGHFARE_NAME: "VICTORIA SQUARE",
|
|
1109
|
+
DEPENDENT_LOCALITY: "",
|
|
1110
|
+
POST_TOWN: "LONDON",
|
|
1111
|
+
POSTCODE: "SW1A 1AA",
|
|
1112
|
+
LOCAL_CUSTODIAN_CODE_DESCRIPTION: "GREATER LONDON",
|
|
1113
|
+
COUNTRY_CODE: "E"
|
|
1114
|
+
}
|
|
1115
|
+
},
|
|
1116
|
+
{
|
|
1117
|
+
properties: {
|
|
1118
|
+
UPRN: "10000003",
|
|
1119
|
+
ADDRESS: "THE GROUND FLOOR, THE OLD GRANARY, 5 CHURCH LANE, LONDON, SW1A 1AA",
|
|
1120
|
+
ORGANISATION_NAME: "OLD GRANARY STUDIOS",
|
|
1121
|
+
SUB_BUILDING_NAME: "GROUND FLOOR",
|
|
1122
|
+
BUILDING_NAME: "THE OLD GRANARY",
|
|
1123
|
+
BUILDING_NUMBER: "5",
|
|
1124
|
+
THOROUGHFARE_NAME: "CHURCH LANE",
|
|
1125
|
+
POST_TOWN: "LONDON",
|
|
1126
|
+
POSTCODE: "SW1A 1AA",
|
|
1127
|
+
LOCAL_CUSTODIAN_CODE_DESCRIPTION: "GREATER LONDON",
|
|
1128
|
+
COUNTRY_CODE: "E"
|
|
1129
|
+
}
|
|
1130
|
+
},
|
|
1131
|
+
{
|
|
1132
|
+
properties: {
|
|
1133
|
+
UPRN: "10000004",
|
|
1134
|
+
ADDRESS: "SUITE 3, WELLINGTON HOUSE, 20 QUEEN STREET, LONDON, SW1A 1AA",
|
|
1135
|
+
ORGANISATION_NAME: "WELLINGTON CONSULTING LTD",
|
|
1136
|
+
DEPARTMENT_NAME: "CLIENT SERVICES",
|
|
1137
|
+
SUB_BUILDING_NAME: "SUITE 3",
|
|
1138
|
+
BUILDING_NAME: "WELLINGTON HOUSE",
|
|
1139
|
+
BUILDING_NUMBER: "20",
|
|
1140
|
+
THOROUGHFARE_NAME: "QUEEN STREET",
|
|
1141
|
+
POST_TOWN: "LONDON",
|
|
1142
|
+
POSTCODE: "SW1A 1AA",
|
|
1143
|
+
LOCAL_CUSTODIAN_CODE_DESCRIPTION: "GREATER LONDON",
|
|
1144
|
+
COUNTRY_CODE: "E"
|
|
1145
|
+
}
|
|
1146
|
+
},
|
|
1147
|
+
{
|
|
1148
|
+
properties: {
|
|
1149
|
+
UPRN: "10000005",
|
|
1150
|
+
ADDRESS: "UNIT 6, MARKET ROW, 3 MARKET YARD, LONDON, SW1A 1AA",
|
|
1151
|
+
ORGANISATION_NAME: "MARKET ROW TRADERS",
|
|
1152
|
+
SUB_BUILDING_NAME: "UNIT 6",
|
|
1153
|
+
BUILDING_NAME: "MARKET ROW",
|
|
1154
|
+
BUILDING_NUMBER: "3",
|
|
1155
|
+
THOROUGHFARE_NAME: "MARKET YARD",
|
|
1156
|
+
POST_TOWN: "LONDON",
|
|
1157
|
+
POSTCODE: "SW1A 1AA",
|
|
1158
|
+
LOCAL_CUSTODIAN_CODE_DESCRIPTION: "GREATER LONDON",
|
|
1159
|
+
COUNTRY_CODE: "E"
|
|
1160
|
+
}
|
|
1161
|
+
},
|
|
1162
|
+
{
|
|
1163
|
+
properties: {
|
|
1164
|
+
UPRN: "20000001",
|
|
1165
|
+
ADDRESS: "1 ORCHARD COTTAGES, WESTFIELD LANE, SHEPTON MALLET, BS14 8XX",
|
|
1166
|
+
BUILDING_NAME: "ORCHARD COTTAGES",
|
|
1167
|
+
BUILDING_NUMBER: "1",
|
|
1168
|
+
THOROUGHFARE_NAME: "WESTFIELD LANE",
|
|
1169
|
+
POST_TOWN: "SHEPTON MALLET",
|
|
1170
|
+
POSTCODE: "BS14 8XX",
|
|
1171
|
+
LOCAL_CUSTODIAN_CODE_DESCRIPTION: "SOMERSET",
|
|
1172
|
+
COUNTRY_CODE: "E"
|
|
1173
|
+
}
|
|
1174
|
+
},
|
|
1175
|
+
{
|
|
1176
|
+
properties: {
|
|
1177
|
+
UPRN: "20000002",
|
|
1178
|
+
ADDRESS: "THE STABLES, MANOR FARM, HOLLOW ROAD, SHEPTON MALLET, BS14 8XX",
|
|
1179
|
+
ORGANISATION_NAME: "MANOR FARM",
|
|
1180
|
+
SUB_BUILDING_NAME: "THE STABLES",
|
|
1181
|
+
BUILDING_NAME: "MANOR FARM",
|
|
1182
|
+
THOROUGHFARE_NAME: "HOLLOW ROAD",
|
|
1183
|
+
POST_TOWN: "SHEPTON MALLET",
|
|
1184
|
+
POSTCODE: "BS14 8XX",
|
|
1185
|
+
LOCAL_CUSTODIAN_CODE_DESCRIPTION: "SOMERSET",
|
|
1186
|
+
COUNTRY_CODE: "E"
|
|
1187
|
+
}
|
|
1188
|
+
},
|
|
1189
|
+
{
|
|
1190
|
+
properties: {
|
|
1191
|
+
UPRN: "30000001",
|
|
1192
|
+
ADDRESS: "FLAT 4, BISHOP COURT, 9 FLEET STREET, LONDON, EC1A 1BB",
|
|
1193
|
+
SUB_BUILDING_NAME: "FLAT 4",
|
|
1194
|
+
BUILDING_NAME: "BISHOP COURT",
|
|
1195
|
+
BUILDING_NUMBER: "9",
|
|
1196
|
+
THOROUGHFARE_NAME: "FLEET STREET",
|
|
1197
|
+
POST_TOWN: "LONDON",
|
|
1198
|
+
POSTCODE: "EC1A 1BB",
|
|
1199
|
+
LOCAL_CUSTODIAN_CODE_DESCRIPTION: "CITY OF LONDON",
|
|
1200
|
+
COUNTRY_CODE: "E"
|
|
1201
|
+
}
|
|
1202
|
+
},
|
|
1203
|
+
{
|
|
1204
|
+
properties: {
|
|
1205
|
+
UPRN: "40000001",
|
|
1206
|
+
ADDRESS: "2A PICCADILLY ARCADE, MANCHESTER, M1 1AE",
|
|
1207
|
+
ORGANISATION_NAME: "PICCADILLY ARCADE LTD",
|
|
1208
|
+
SUB_BUILDING_NAME: "2A",
|
|
1209
|
+
BUILDING_NAME: "PICCADILLY ARCADE",
|
|
1210
|
+
BUILDING_NUMBER: "2A",
|
|
1211
|
+
THOROUGHFARE_NAME: "PICCADILLY",
|
|
1212
|
+
POST_TOWN: "MANCHESTER",
|
|
1213
|
+
POSTCODE: "M1 1AE",
|
|
1214
|
+
LOCAL_CUSTODIAN_CODE_DESCRIPTION: "GREATER MANCHESTER",
|
|
1215
|
+
COUNTRY_CODE: "E"
|
|
1216
|
+
}
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
properties: {
|
|
1220
|
+
UPRN: "50000001",
|
|
1221
|
+
ADDRESS: "3 WESTBOURNE TERRACE, LONDON, W1A 0AX",
|
|
1222
|
+
BUILDING_NAME: "WESTBOURNE TERRACE",
|
|
1223
|
+
BUILDING_NUMBER: "3",
|
|
1224
|
+
THOROUGHFARE_NAME: "WESTBOURNE TERRACE",
|
|
1225
|
+
POST_TOWN: "LONDON",
|
|
1226
|
+
POSTCODE: "W1A 0AX",
|
|
1227
|
+
LOCAL_CUSTODIAN_CODE_DESCRIPTION: "WESTMINSTER",
|
|
1228
|
+
COUNTRY_CODE: "E"
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
];
|
|
1232
|
+
|
|
1233
|
+
// src/services/os-places/os-places-stub.js
|
|
1234
|
+
var mockPostcode = (postcode) => {
|
|
1235
|
+
const formattedPostcode = postcode == null ? void 0 : postcode.toUpperCase().replaceAll(" ", "");
|
|
1236
|
+
const matchingAddresses = mockAddresses.filter((address) => {
|
|
1237
|
+
var _a;
|
|
1238
|
+
const addressPostcode = (_a = address.properties.POSTCODE) == null ? void 0 : _a.toUpperCase().replaceAll(" ", "");
|
|
1239
|
+
return addressPostcode === formattedPostcode;
|
|
1240
|
+
});
|
|
1241
|
+
return {
|
|
1242
|
+
features: matchingAddresses
|
|
1243
|
+
};
|
|
1244
|
+
};
|
|
1245
|
+
|
|
1246
|
+
// src/services/os-places/address-lookup-service.js
|
|
1247
|
+
var addressLookupService = async (postcode, osPlacesConfig) => {
|
|
1248
|
+
const addresses = await fetchAddressesFromPostcodeLookup(postcode, osPlacesConfig);
|
|
1249
|
+
if (addresses.error) {
|
|
1250
|
+
return addresses;
|
|
1251
|
+
}
|
|
1252
|
+
if (!(addresses == null ? void 0 : addresses.length)) {
|
|
1253
|
+
return {
|
|
1254
|
+
error: [
|
|
1255
|
+
{
|
|
1256
|
+
message: "No addresses found for this postcode",
|
|
1257
|
+
path: ["postcode"]
|
|
1258
|
+
}
|
|
1259
|
+
]
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
const mappedAddresses = addressLookupMapper(addresses);
|
|
1263
|
+
return mappedAddresses;
|
|
1264
|
+
};
|
|
1265
|
+
var fetchAddressesFromPostcodeLookup = async (postcode, osPlacesConfig) => {
|
|
1266
|
+
const MAX_RETRIES = 3;
|
|
1267
|
+
const INITIAL_BACKOFF_MS = 100;
|
|
1268
|
+
for (let attemptNumber = 1; attemptNumber <= MAX_RETRIES; attemptNumber++) {
|
|
1269
|
+
try {
|
|
1270
|
+
const { clientId, osPlacesStub } = osPlacesConfig;
|
|
1271
|
+
if (osPlacesStub) {
|
|
1272
|
+
const response2 = mockPostcode(postcode);
|
|
1273
|
+
return response2.features ?? [];
|
|
1274
|
+
}
|
|
1275
|
+
const response = await fetchFromPlacesAPI(clientId, postcode);
|
|
1276
|
+
return response.features ?? [];
|
|
1277
|
+
} catch (error) {
|
|
1278
|
+
const shouldRetry = isRetryable(error) && attemptNumber < MAX_RETRIES;
|
|
1279
|
+
if (!shouldRetry) {
|
|
1280
|
+
return buildErrorResponse(error.message);
|
|
1281
|
+
}
|
|
1282
|
+
const backoffMs = calculateExponentialBackoff(attemptNumber, INITIAL_BACKOFF_MS);
|
|
1283
|
+
await delayBeforeRetry(backoffMs);
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
};
|
|
1287
|
+
var calculateExponentialBackoff = (attemptNumber, baseMs) => {
|
|
1288
|
+
const exponent = attemptNumber - 1;
|
|
1289
|
+
const powerOf2 = Math.pow(2, exponent);
|
|
1290
|
+
const backoffDuration = baseMs * powerOf2;
|
|
1291
|
+
return backoffDuration;
|
|
1292
|
+
};
|
|
1293
|
+
function delayBeforeRetry(ms) {
|
|
1294
|
+
const callback = (resolve) => {
|
|
1295
|
+
setTimeout(resolve, ms);
|
|
1296
|
+
};
|
|
1297
|
+
return new Promise(callback);
|
|
1298
|
+
}
|
|
1299
|
+
var buildErrorResponse = (message) => {
|
|
1300
|
+
return {
|
|
1301
|
+
error: [
|
|
1302
|
+
{
|
|
1303
|
+
message: message || "Failed to fetch addresses",
|
|
1304
|
+
path: ["postcode"]
|
|
1305
|
+
}
|
|
1306
|
+
]
|
|
1307
|
+
};
|
|
1308
|
+
};
|
|
1309
|
+
var fetchFromPlacesAPI = async (clientId, postcode) => {
|
|
1310
|
+
const response = await import_osdatahub.placesAPI.postcode(clientId, postcode, { limit: 150 });
|
|
1311
|
+
return response;
|
|
1312
|
+
};
|
|
1313
|
+
var isRetryable = (error) => {
|
|
1314
|
+
const networkErrors = ["ECONNRESET", "ECONNREFUSED", "ETIMEDOUT"];
|
|
1315
|
+
if (networkErrors.includes(error.code)) {
|
|
1316
|
+
return true;
|
|
1317
|
+
}
|
|
1318
|
+
if (error.status && error.status >= INTERNAL_SERVER_ERROR) {
|
|
1319
|
+
return true;
|
|
1320
|
+
}
|
|
1321
|
+
return false;
|
|
1322
|
+
};
|
|
1323
|
+
|
|
1324
|
+
// src/services/services.js
|
|
1325
|
+
var services = {
|
|
1326
|
+
addressLookup: addressLookupService
|
|
1327
|
+
};
|
|
1013
1328
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1014
1329
|
0 && (module.exports = {
|
|
1015
1330
|
constants,
|
|
@@ -1017,5 +1332,6 @@ var utils = {
|
|
|
1017
1332
|
mutations,
|
|
1018
1333
|
presenters,
|
|
1019
1334
|
schemas,
|
|
1335
|
+
services,
|
|
1020
1336
|
utils
|
|
1021
1337
|
});
|