@defra/forms-engine-plugin 4.14.3 → 4.14.4
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/.server/server/plugins/engine/components/TelephoneNumberField.js +2 -4
- package/.server/server/plugins/engine/components/TelephoneNumberField.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/telephone.d.ts +0 -4
- package/.server/server/plugins/engine/components/helpers/telephone.js +6 -20
- package/.server/server/plugins/engine/components/helpers/telephone.js.map +1 -1
- package/.server/server/plugins/engine/components/helpers/telephone.test.js +5 -5
- package/.server/server/plugins/engine/components/helpers/telephone.test.js.map +1 -1
- package/package.json +1 -1
- package/src/server/plugins/engine/components/TelephoneNumberField.ts +1 -5
- package/src/server/plugins/engine/components/helpers/telephone.ts +11 -35
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FormComponent } from "./FormComponent.js";
|
|
2
2
|
import { addClassOptionIfNone } from "./helpers/index.js";
|
|
3
|
-
import {
|
|
3
|
+
import { INVALID_ERROR_CODE, joi } from "./helpers/telephone.js";
|
|
4
4
|
import { messageTemplate } from "../pageControllers/validationOptions.js";
|
|
5
5
|
export class TelephoneNumberField extends FormComponent {
|
|
6
6
|
constructor(def, props) {
|
|
@@ -23,9 +23,7 @@ export class TelephoneNumberField extends FormComponent {
|
|
|
23
23
|
'any.required': message,
|
|
24
24
|
'string.empty': message,
|
|
25
25
|
'string.pattern.base': message,
|
|
26
|
-
[INVALID_ERROR_CODE]: message
|
|
27
|
-
[UK_ERROR_CODE]: message,
|
|
28
|
-
[INTERNATIONAL_ERROR_CODE]: message
|
|
26
|
+
[INVALID_ERROR_CODE]: message
|
|
29
27
|
});
|
|
30
28
|
} else if (options.customValidationMessages) {
|
|
31
29
|
formSchema = formSchema.messages(options.customValidationMessages);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TelephoneNumberField.js","names":["FormComponent","addClassOptionIfNone","
|
|
1
|
+
{"version":3,"file":"TelephoneNumberField.js","names":["FormComponent","addClassOptionIfNone","INVALID_ERROR_CODE","joi","messageTemplate","TelephoneNumberField","constructor","def","props","options","format","formSchema","string","trim","phoneNumber","label","required","allow","customValidationMessage","message","messages","customValidationMessages","default","stateSchema","getViewModel","payload","errors","viewModel","attributes","autocomplete","type","getAllPossibleErrors","baseErrors","template","advancedSettingsErrors"],"sources":["../../../../../src/server/plugins/engine/components/TelephoneNumberField.ts"],"sourcesContent":["import { type TelephoneNumberFieldComponent } from '@defra/forms-model'\nimport { type StringSchema } from 'joi'\n\nimport { FormComponent } from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { addClassOptionIfNone } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport {\n INVALID_ERROR_CODE,\n joi\n} from '~/src/server/plugins/engine/components/helpers/telephone.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormSubmissionError\n} from '~/src/server/plugins/engine/types.js'\n\nexport class TelephoneNumberField extends FormComponent {\n declare options: TelephoneNumberFieldComponent['options']\n declare formSchema: StringSchema\n declare stateSchema: StringSchema\n\n constructor(\n def: TelephoneNumberFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { options } = def\n const { format } = options\n\n let formSchema = joi\n .string()\n .trim()\n .phoneNumber({ format })\n .label(this.label)\n .required()\n\n if (options.required === false) {\n formSchema = formSchema.allow('')\n }\n\n if (options.customValidationMessage) {\n const message = options.customValidationMessage\n\n formSchema = formSchema.messages({\n 'any.required': message,\n 'string.empty': message,\n 'string.pattern.base': message,\n [INVALID_ERROR_CODE]: message\n })\n } else if (options.customValidationMessages) {\n formSchema = formSchema.messages(options.customValidationMessages)\n }\n\n addClassOptionIfNone(options, 'govuk-input--width-20')\n\n this.formSchema = formSchema.default('')\n this.stateSchema = formSchema.default(null).allow(null)\n this.options = options\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const viewModel = super.getViewModel(payload, errors)\n const { attributes } = viewModel\n\n attributes.autocomplete = 'tel'\n\n return {\n ...viewModel,\n type: 'tel'\n }\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return TelephoneNumberField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: messageTemplate.required },\n { type: 'format', template: messageTemplate.format }\n ],\n advancedSettingsErrors: []\n }\n }\n}\n"],"mappings":"AAGA,SAASA,aAAa;AACtB,SAASC,oBAAoB;AAC7B,SACEC,kBAAkB,EAClBC,GAAG;AAEL,SAASC,eAAe;AAOxB,OAAO,MAAMC,oBAAoB,SAASL,aAAa,CAAC;EAKtDM,WAAWA,CACTC,GAAkC,EAClCC,KAAqD,EACrD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAM;MAAEC;IAAQ,CAAC,GAAGF,GAAG;IACvB,MAAM;MAAEG;IAAO,CAAC,GAAGD,OAAO;IAE1B,IAAIE,UAAU,GAAGR,GAAG,CACjBS,MAAM,CAAC,CAAC,CACRC,IAAI,CAAC,CAAC,CACNC,WAAW,CAAC;MAAEJ;IAAO,CAAC,CAAC,CACvBK,KAAK,CAAC,IAAI,CAACA,KAAK,CAAC,CACjBC,QAAQ,CAAC,CAAC;IAEb,IAAIP,OAAO,CAACO,QAAQ,KAAK,KAAK,EAAE;MAC9BL,UAAU,GAAGA,UAAU,CAACM,KAAK,CAAC,EAAE,CAAC;IACnC;IAEA,IAAIR,OAAO,CAACS,uBAAuB,EAAE;MACnC,MAAMC,OAAO,GAAGV,OAAO,CAACS,uBAAuB;MAE/CP,UAAU,GAAGA,UAAU,CAACS,QAAQ,CAAC;QAC/B,cAAc,EAAED,OAAO;QACvB,cAAc,EAAEA,OAAO;QACvB,qBAAqB,EAAEA,OAAO;QAC9B,CAACjB,kBAAkB,GAAGiB;MACxB,CAAC,CAAC;IACJ,CAAC,MAAM,IAAIV,OAAO,CAACY,wBAAwB,EAAE;MAC3CV,UAAU,GAAGA,UAAU,CAACS,QAAQ,CAACX,OAAO,CAACY,wBAAwB,CAAC;IACpE;IAEApB,oBAAoB,CAACQ,OAAO,EAAE,uBAAuB,CAAC;IAEtD,IAAI,CAACE,UAAU,GAAGA,UAAU,CAACW,OAAO,CAAC,EAAE,CAAC;IACxC,IAAI,CAACC,WAAW,GAAGZ,UAAU,CAACW,OAAO,CAAC,IAAI,CAAC,CAACL,KAAK,CAAC,IAAI,CAAC;IACvD,IAAI,CAACR,OAAO,GAAGA,OAAO;EACxB;EAEAe,YAAYA,CAACC,OAAoB,EAAEC,MAA8B,EAAE;IACjE,MAAMC,SAAS,GAAG,KAAK,CAACH,YAAY,CAACC,OAAO,EAAEC,MAAM,CAAC;IACrD,MAAM;MAAEE;IAAW,CAAC,GAAGD,SAAS;IAEhCC,UAAU,CAACC,YAAY,GAAG,KAAK;IAE/B,OAAO;MACL,GAAGF,SAAS;MACZG,IAAI,EAAE;IACR,CAAC;EACH;;EAEA;AACF;AACA;EACEC,oBAAoBA,CAAA,EAA6B;IAC/C,OAAO1B,oBAAoB,CAAC0B,oBAAoB,CAAC,CAAC;EACpD;;EAEA;AACF;AACA;EACE,OAAOA,oBAAoBA,CAAA,EAA6B;IACtD,OAAO;MACLC,UAAU,EAAE,CACV;QAAEF,IAAI,EAAE,UAAU;QAAEG,QAAQ,EAAE7B,eAAe,CAACY;MAAS,CAAC,EACxD;QAAEc,IAAI,EAAE,QAAQ;QAAEG,QAAQ,EAAE7B,eAAe,CAACM;MAAO,CAAC,CACrD;MACDwB,sBAAsB,EAAE;IAC1B,CAAC;EACH;AACF","ignoreList":[]}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import { TelephoneNumberFieldOptionsFormatEnum } from '@defra/forms-model';
|
|
2
1
|
import LibPhoneNumber from 'google-libphonenumber';
|
|
3
2
|
import JoiBase from 'joi';
|
|
4
3
|
export declare const COUNTRY = "GB";
|
|
5
4
|
export declare const INVALID_ERROR_CODE = "phoneNumber.invalid";
|
|
6
|
-
export declare const UK_ERROR_CODE = "phoneNumber.uk";
|
|
7
|
-
export declare const INTERNATIONAL_ERROR_CODE = "phoneNumber.international";
|
|
8
5
|
export declare const isUKNumber: (value: LibPhoneNumber.PhoneNumber) => boolean;
|
|
9
|
-
export declare function getErrorCode(format?: TelephoneNumberFieldOptionsFormatEnum): "phoneNumber.invalid" | "phoneNumber.uk" | "phoneNumber.international";
|
|
10
6
|
export declare const joi: JoiBase.Root;
|
|
@@ -1,30 +1,18 @@
|
|
|
1
1
|
import { TelephoneNumberFieldOptionsFormatEnum } from '@defra/forms-model';
|
|
2
2
|
import LibPhoneNumber from 'google-libphonenumber';
|
|
3
3
|
import JoiBase from 'joi';
|
|
4
|
-
import {
|
|
4
|
+
import { messageTemplate } from "../../pageControllers/validationOptions.js";
|
|
5
5
|
const phoneUtil = LibPhoneNumber.PhoneNumberUtil.getInstance();
|
|
6
6
|
export const COUNTRY = 'GB';
|
|
7
7
|
export const INVALID_ERROR_CODE = 'phoneNumber.invalid';
|
|
8
|
-
export const UK_ERROR_CODE = 'phoneNumber.uk';
|
|
9
|
-
export const INTERNATIONAL_ERROR_CODE = 'phoneNumber.international';
|
|
10
8
|
export const isUKNumber = value => {
|
|
11
9
|
return phoneUtil.isValidNumberForRegion(value, COUNTRY);
|
|
12
10
|
};
|
|
13
|
-
export function getErrorCode(format) {
|
|
14
|
-
if (format === TelephoneNumberFieldOptionsFormatEnum.UK) {
|
|
15
|
-
return UK_ERROR_CODE;
|
|
16
|
-
} else if (format === TelephoneNumberFieldOptionsFormatEnum.International) {
|
|
17
|
-
return INTERNATIONAL_ERROR_CODE;
|
|
18
|
-
}
|
|
19
|
-
return INVALID_ERROR_CODE;
|
|
20
|
-
}
|
|
21
11
|
export const joi = JoiBase.extend({
|
|
22
12
|
type: 'string',
|
|
23
13
|
base: JoiBase.string(),
|
|
24
14
|
messages: {
|
|
25
|
-
[INVALID_ERROR_CODE]:
|
|
26
|
-
[UK_ERROR_CODE]: JoiBase.expression('Enter {{lowerFirst(#label)}}, like 01632 960 001, 07700 900 982 or +44 808 157 0192', opts),
|
|
27
|
-
[INTERNATIONAL_ERROR_CODE]: JoiBase.expression('Enter {{lowerFirst(#label)}}, starting with + and the country code, for example +92333 1234567 or 00923331234567', opts)
|
|
15
|
+
[INVALID_ERROR_CODE]: messageTemplate.format
|
|
28
16
|
},
|
|
29
17
|
rules: {
|
|
30
18
|
phoneNumber: {
|
|
@@ -50,19 +38,17 @@ export const joi = JoiBase.extend({
|
|
|
50
38
|
try {
|
|
51
39
|
const parsed = phoneUtil.parse(value, COUNTRY);
|
|
52
40
|
if (!phoneUtil.isValidNumber(parsed)) {
|
|
53
|
-
return error(
|
|
41
|
+
return error(INVALID_ERROR_CODE);
|
|
54
42
|
}
|
|
55
43
|
if (format) {
|
|
56
44
|
const isUK = isUKNumber(parsed);
|
|
57
|
-
if (!isUK && format === TelephoneNumberFieldOptionsFormatEnum.UK) {
|
|
58
|
-
return error(
|
|
59
|
-
} else if (isUK && format === TelephoneNumberFieldOptionsFormatEnum.International) {
|
|
60
|
-
return error(INTERNATIONAL_ERROR_CODE);
|
|
45
|
+
if (!isUK && format === TelephoneNumberFieldOptionsFormatEnum.UK || isUK && format === TelephoneNumberFieldOptionsFormatEnum.International) {
|
|
46
|
+
return error(INVALID_ERROR_CODE);
|
|
61
47
|
}
|
|
62
48
|
}
|
|
63
49
|
return value;
|
|
64
50
|
} catch {
|
|
65
|
-
return error(
|
|
51
|
+
return error(INVALID_ERROR_CODE);
|
|
66
52
|
}
|
|
67
53
|
}
|
|
68
54
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telephone.js","names":["TelephoneNumberFieldOptionsFormatEnum","LibPhoneNumber","JoiBase","
|
|
1
|
+
{"version":3,"file":"telephone.js","names":["TelephoneNumberFieldOptionsFormatEnum","LibPhoneNumber","JoiBase","messageTemplate","phoneUtil","PhoneNumberUtil","getInstance","COUNTRY","INVALID_ERROR_CODE","isUKNumber","value","isValidNumberForRegion","joi","extend","type","base","string","messages","format","rules","phoneNumber","method","$_addRule","name","args","ref","assert","valid","International","UK","validate","error","parsed","parse","isValidNumber","isUK"],"sources":["../../../../../../src/server/plugins/engine/components/helpers/telephone.ts"],"sourcesContent":["import { TelephoneNumberFieldOptionsFormatEnum } from '@defra/forms-model'\nimport LibPhoneNumber from 'google-libphonenumber'\nimport JoiBase, { type LanguageMessages } from 'joi'\n\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\n\nconst phoneUtil = LibPhoneNumber.PhoneNumberUtil.getInstance()\n\nexport const COUNTRY = 'GB'\nexport const INVALID_ERROR_CODE = 'phoneNumber.invalid'\n\nexport const isUKNumber = (value: LibPhoneNumber.PhoneNumber) => {\n return phoneUtil.isValidNumberForRegion(value, COUNTRY)\n}\n\nexport const joi = JoiBase.extend({\n type: 'string',\n base: JoiBase.string(),\n messages: {\n [INVALID_ERROR_CODE]: messageTemplate.format\n } as LanguageMessages,\n rules: {\n phoneNumber: {\n method({\n format\n }: { format?: TelephoneNumberFieldOptionsFormatEnum } = {}) {\n return this.$_addRule({\n name: 'phoneNumber',\n args: { format }\n })\n },\n args: [\n {\n name: 'format',\n ref: true,\n assert: JoiBase.valid(\n TelephoneNumberFieldOptionsFormatEnum.International,\n TelephoneNumberFieldOptionsFormatEnum.UK\n )\n }\n ],\n validate(value, { error }, args) {\n const format = args.format\n\n try {\n const parsed = phoneUtil.parse(value, COUNTRY)\n\n if (!phoneUtil.isValidNumber(parsed)) {\n return error(INVALID_ERROR_CODE)\n }\n\n if (format) {\n const isUK = isUKNumber(parsed)\n\n if (\n (!isUK && format === TelephoneNumberFieldOptionsFormatEnum.UK) ||\n (isUK &&\n format === TelephoneNumberFieldOptionsFormatEnum.International)\n ) {\n return error(INVALID_ERROR_CODE)\n }\n }\n\n return value\n } catch {\n return error(INVALID_ERROR_CODE)\n }\n }\n }\n }\n}) as JoiBase.Root\n"],"mappings":"AAAA,SAASA,qCAAqC,QAAQ,oBAAoB;AAC1E,OAAOC,cAAc,MAAM,uBAAuB;AAClD,OAAOC,OAAO,MAAiC,KAAK;AAEpD,SAASC,eAAe;AAExB,MAAMC,SAAS,GAAGH,cAAc,CAACI,eAAe,CAACC,WAAW,CAAC,CAAC;AAE9D,OAAO,MAAMC,OAAO,GAAG,IAAI;AAC3B,OAAO,MAAMC,kBAAkB,GAAG,qBAAqB;AAEvD,OAAO,MAAMC,UAAU,GAAIC,KAAiC,IAAK;EAC/D,OAAON,SAAS,CAACO,sBAAsB,CAACD,KAAK,EAAEH,OAAO,CAAC;AACzD,CAAC;AAED,OAAO,MAAMK,GAAG,GAAGV,OAAO,CAACW,MAAM,CAAC;EAChCC,IAAI,EAAE,QAAQ;EACdC,IAAI,EAAEb,OAAO,CAACc,MAAM,CAAC,CAAC;EACtBC,QAAQ,EAAE;IACR,CAACT,kBAAkB,GAAGL,eAAe,CAACe;EACxC,CAAqB;EACrBC,KAAK,EAAE;IACLC,WAAW,EAAE;MACXC,MAAMA,CAAC;QACLH;MACkD,CAAC,GAAG,CAAC,CAAC,EAAE;QAC1D,OAAO,IAAI,CAACI,SAAS,CAAC;UACpBC,IAAI,EAAE,aAAa;UACnBC,IAAI,EAAE;YAAEN;UAAO;QACjB,CAAC,CAAC;MACJ,CAAC;MACDM,IAAI,EAAE,CACJ;QACED,IAAI,EAAE,QAAQ;QACdE,GAAG,EAAE,IAAI;QACTC,MAAM,EAAExB,OAAO,CAACyB,KAAK,CACnB3B,qCAAqC,CAAC4B,aAAa,EACnD5B,qCAAqC,CAAC6B,EACxC;MACF,CAAC,CACF;MACDC,QAAQA,CAACpB,KAAK,EAAE;QAAEqB;MAAM,CAAC,EAAEP,IAAI,EAAE;QAC/B,MAAMN,MAAM,GAAGM,IAAI,CAACN,MAAM;QAE1B,IAAI;UACF,MAAMc,MAAM,GAAG5B,SAAS,CAAC6B,KAAK,CAACvB,KAAK,EAAEH,OAAO,CAAC;UAE9C,IAAI,CAACH,SAAS,CAAC8B,aAAa,CAACF,MAAM,CAAC,EAAE;YACpC,OAAOD,KAAK,CAACvB,kBAAkB,CAAC;UAClC;UAEA,IAAIU,MAAM,EAAE;YACV,MAAMiB,IAAI,GAAG1B,UAAU,CAACuB,MAAM,CAAC;YAE/B,IACG,CAACG,IAAI,IAAIjB,MAAM,KAAKlB,qCAAqC,CAAC6B,EAAE,IAC5DM,IAAI,IACHjB,MAAM,KAAKlB,qCAAqC,CAAC4B,aAAc,EACjE;cACA,OAAOG,KAAK,CAACvB,kBAAkB,CAAC;YAClC;UACF;UAEA,OAAOE,KAAK;QACd,CAAC,CAAC,MAAM;UACN,OAAOqB,KAAK,CAACvB,kBAAkB,CAAC;QAClC;MACF;IACF;EACF;AACF,CAAC,CAAiB","ignoreList":[]}
|
|
@@ -24,7 +24,7 @@ describe('Telephone validation helpers', () => {
|
|
|
24
24
|
}).label('Home phone');
|
|
25
25
|
const result = telephoneSchema.validate('ABC');
|
|
26
26
|
expect(result.error).toBeDefined();
|
|
27
|
-
expect(result.error?.message).toBe('Enter home phone
|
|
27
|
+
expect(result.error?.message).toBe('Enter home phone in the correct format');
|
|
28
28
|
expect(result.value).toBe('ABC');
|
|
29
29
|
});
|
|
30
30
|
test('it should have errors for international telephone number', () => {
|
|
@@ -33,7 +33,7 @@ describe('Telephone validation helpers', () => {
|
|
|
33
33
|
}).label('Home phone');
|
|
34
34
|
const result = telephoneSchema.validate('+1-212-456-7890');
|
|
35
35
|
expect(result.error).toBeDefined();
|
|
36
|
-
expect(result.error?.message).toBe('Enter home phone
|
|
36
|
+
expect(result.error?.message).toBe('Enter home phone in the correct format');
|
|
37
37
|
expect(result.value).toBe('+1-212-456-7890');
|
|
38
38
|
});
|
|
39
39
|
});
|
|
@@ -52,7 +52,7 @@ describe('Telephone validation helpers', () => {
|
|
|
52
52
|
}).label('Home phone');
|
|
53
53
|
const result = telephoneSchema.validate('ABC');
|
|
54
54
|
expect(result.error).toBeDefined();
|
|
55
|
-
expect(result.error?.message).toBe('Enter home phone
|
|
55
|
+
expect(result.error?.message).toBe('Enter home phone in the correct format');
|
|
56
56
|
expect(result.value).toBe('ABC');
|
|
57
57
|
});
|
|
58
58
|
test('it should have errors for UK phone number in international format', () => {
|
|
@@ -61,7 +61,7 @@ describe('Telephone validation helpers', () => {
|
|
|
61
61
|
}).label('Home phone');
|
|
62
62
|
const result = telephoneSchema.validate('+44 1606 76477');
|
|
63
63
|
expect(result.error).toBeDefined();
|
|
64
|
-
expect(result.error?.message).toBe('Enter home phone
|
|
64
|
+
expect(result.error?.message).toBe('Enter home phone in the correct format');
|
|
65
65
|
expect(result.value).toBe('+44 1606 76477');
|
|
66
66
|
});
|
|
67
67
|
});
|
|
@@ -82,7 +82,7 @@ describe('Telephone validation helpers', () => {
|
|
|
82
82
|
const telephoneSchema = joi.string().phoneNumber().label('Home phone');
|
|
83
83
|
const result = telephoneSchema.validate('ABC');
|
|
84
84
|
expect(result.error).toBeDefined();
|
|
85
|
-
expect(result.error?.message).toBe('Enter home phone
|
|
85
|
+
expect(result.error?.message).toBe('Enter home phone in the correct format');
|
|
86
86
|
expect(result.value).toBe('ABC');
|
|
87
87
|
});
|
|
88
88
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telephone.test.js","names":["TelephoneNumberFieldOptionsFormatEnum","joi","describe","test","telephoneSchema","string","phoneNumber","format","UK","label","result","validate","expect","error","toBeUndefined","value","toBe","toBeDefined","message","International"],"sources":["../../../../../../src/server/plugins/engine/components/helpers/telephone.test.js"],"sourcesContent":["import { TelephoneNumberFieldOptionsFormatEnum } from '@defra/forms-model'\n\nimport { joi } from '~/src/server/plugins/engine/components/helpers/telephone.js'\n\ndescribe('Telephone validation helpers', () => {\n describe('UK numbers', () => {\n test('it should not have errors for valid telephone number', () => {\n const telephoneSchema = joi\n .string()\n .phoneNumber({ format: TelephoneNumberFieldOptionsFormatEnum.UK })\n .label('Home phone')\n\n const result = telephoneSchema.validate('0160676477')\n\n expect(result.error).toBeUndefined()\n expect(result.value).toBe('0160676477')\n })\n\n test('it should not have errors for valid UK telephone number in international format', () => {\n const telephoneSchema = joi\n .string()\n .phoneNumber({ format: TelephoneNumberFieldOptionsFormatEnum.UK })\n .label('Home phone')\n\n const result = telephoneSchema.validate('+44 1606 76477')\n\n expect(result.error).toBeUndefined()\n expect(result.value).toBe('+44 1606 76477')\n })\n\n test('it should have errors for invalid telephone number', () => {\n const telephoneSchema = joi\n .string()\n .phoneNumber({ format: TelephoneNumberFieldOptionsFormatEnum.UK })\n .label('Home phone')\n\n const result = telephoneSchema.validate('ABC')\n\n expect(result.error).toBeDefined()\n expect(result.error?.message).toBe(\n 'Enter home phone
|
|
1
|
+
{"version":3,"file":"telephone.test.js","names":["TelephoneNumberFieldOptionsFormatEnum","joi","describe","test","telephoneSchema","string","phoneNumber","format","UK","label","result","validate","expect","error","toBeUndefined","value","toBe","toBeDefined","message","International"],"sources":["../../../../../../src/server/plugins/engine/components/helpers/telephone.test.js"],"sourcesContent":["import { TelephoneNumberFieldOptionsFormatEnum } from '@defra/forms-model'\n\nimport { joi } from '~/src/server/plugins/engine/components/helpers/telephone.js'\n\ndescribe('Telephone validation helpers', () => {\n describe('UK numbers', () => {\n test('it should not have errors for valid telephone number', () => {\n const telephoneSchema = joi\n .string()\n .phoneNumber({ format: TelephoneNumberFieldOptionsFormatEnum.UK })\n .label('Home phone')\n\n const result = telephoneSchema.validate('0160676477')\n\n expect(result.error).toBeUndefined()\n expect(result.value).toBe('0160676477')\n })\n\n test('it should not have errors for valid UK telephone number in international format', () => {\n const telephoneSchema = joi\n .string()\n .phoneNumber({ format: TelephoneNumberFieldOptionsFormatEnum.UK })\n .label('Home phone')\n\n const result = telephoneSchema.validate('+44 1606 76477')\n\n expect(result.error).toBeUndefined()\n expect(result.value).toBe('+44 1606 76477')\n })\n\n test('it should have errors for invalid telephone number', () => {\n const telephoneSchema = joi\n .string()\n .phoneNumber({ format: TelephoneNumberFieldOptionsFormatEnum.UK })\n .label('Home phone')\n\n const result = telephoneSchema.validate('ABC')\n\n expect(result.error).toBeDefined()\n expect(result.error?.message).toBe(\n 'Enter home phone in the correct format'\n )\n expect(result.value).toBe('ABC')\n })\n\n test('it should have errors for international telephone number', () => {\n const telephoneSchema = joi\n .string()\n .phoneNumber({ format: TelephoneNumberFieldOptionsFormatEnum.UK })\n .label('Home phone')\n\n const result = telephoneSchema.validate('+1-212-456-7890')\n\n expect(result.error).toBeDefined()\n expect(result.error?.message).toBe(\n 'Enter home phone in the correct format'\n )\n expect(result.value).toBe('+1-212-456-7890')\n })\n })\n\n describe('International numbers', () => {\n test('it should not have errors for valid telephone number', () => {\n const telephoneSchema = joi\n .string()\n .phoneNumber({\n format: TelephoneNumberFieldOptionsFormatEnum.International\n })\n .label('Home phone')\n\n const result = telephoneSchema.validate('+1-212-456-7890')\n\n expect(result.error).toBeUndefined()\n expect(result.value).toBe('+1-212-456-7890')\n })\n\n test('it should have errors for invalid telephone number', () => {\n const telephoneSchema = joi\n .string()\n .phoneNumber({\n format: TelephoneNumberFieldOptionsFormatEnum.International\n })\n .label('Home phone')\n\n const result = telephoneSchema.validate('ABC')\n\n expect(result.error).toBeDefined()\n expect(result.error?.message).toBe(\n 'Enter home phone in the correct format'\n )\n expect(result.value).toBe('ABC')\n })\n\n test('it should have errors for UK phone number in international format', () => {\n const telephoneSchema = joi\n .string()\n .phoneNumber({\n format: TelephoneNumberFieldOptionsFormatEnum.International\n })\n .label('Home phone')\n\n const result = telephoneSchema.validate('+44 1606 76477')\n\n expect(result.error).toBeDefined()\n expect(result.error?.message).toBe(\n 'Enter home phone in the correct format'\n )\n expect(result.value).toBe('+44 1606 76477')\n })\n })\n\n describe('Any format', () => {\n test('it should not have errors for valid national telephone number', () => {\n const telephoneSchema = joi.string().phoneNumber().label('Home phone')\n\n const result = telephoneSchema.validate('0160676477')\n\n expect(result.error).toBeUndefined()\n expect(result.value).toBe('0160676477')\n })\n\n test('it should not have errors for valid international telephone number', () => {\n const telephoneSchema = joi.string().phoneNumber().label('Home phone')\n\n const result = telephoneSchema.validate('+1-212-456-7890')\n\n expect(result.error).toBeUndefined()\n expect(result.value).toBe('+1-212-456-7890')\n })\n\n test('it should have errors for invalid telephone number', () => {\n const telephoneSchema = joi.string().phoneNumber().label('Home phone')\n\n const result = telephoneSchema.validate('ABC')\n\n expect(result.error).toBeDefined()\n expect(result.error?.message).toBe(\n 'Enter home phone in the correct format'\n )\n expect(result.value).toBe('ABC')\n })\n })\n})\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -4,9 +4,7 @@ import { type StringSchema } from 'joi'
|
|
|
4
4
|
import { FormComponent } from './FormComponent.js'
|
|
5
5
|
import { addClassOptionIfNone } from './helpers/index.js'
|
|
6
6
|
import {
|
|
7
|
-
INTERNATIONAL_ERROR_CODE,
|
|
8
7
|
INVALID_ERROR_CODE,
|
|
9
|
-
UK_ERROR_CODE,
|
|
10
8
|
joi
|
|
11
9
|
} from './helpers/telephone.js'
|
|
12
10
|
import { messageTemplate } from '../pageControllers/validationOptions.js'
|
|
@@ -48,9 +46,7 @@ export class TelephoneNumberField extends FormComponent {
|
|
|
48
46
|
'any.required': message,
|
|
49
47
|
'string.empty': message,
|
|
50
48
|
'string.pattern.base': message,
|
|
51
|
-
[INVALID_ERROR_CODE]: message
|
|
52
|
-
[UK_ERROR_CODE]: message,
|
|
53
|
-
[INTERNATIONAL_ERROR_CODE]: message
|
|
49
|
+
[INVALID_ERROR_CODE]: message
|
|
54
50
|
})
|
|
55
51
|
} else if (options.customValidationMessages) {
|
|
56
52
|
formSchema = formSchema.messages(options.customValidationMessages)
|
|
@@ -1,47 +1,24 @@
|
|
|
1
1
|
import { TelephoneNumberFieldOptionsFormatEnum } from '@defra/forms-model'
|
|
2
2
|
import LibPhoneNumber from 'google-libphonenumber'
|
|
3
|
-
import JoiBase, { type
|
|
3
|
+
import JoiBase, { type LanguageMessages } from 'joi'
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { messageTemplate } from '../../pageControllers/validationOptions.js'
|
|
6
6
|
|
|
7
7
|
const phoneUtil = LibPhoneNumber.PhoneNumberUtil.getInstance()
|
|
8
8
|
|
|
9
9
|
export const COUNTRY = 'GB'
|
|
10
10
|
export const INVALID_ERROR_CODE = 'phoneNumber.invalid'
|
|
11
|
-
export const UK_ERROR_CODE = 'phoneNumber.uk'
|
|
12
|
-
export const INTERNATIONAL_ERROR_CODE = 'phoneNumber.international'
|
|
13
11
|
|
|
14
12
|
export const isUKNumber = (value: LibPhoneNumber.PhoneNumber) => {
|
|
15
13
|
return phoneUtil.isValidNumberForRegion(value, COUNTRY)
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
export function getErrorCode(format?: TelephoneNumberFieldOptionsFormatEnum) {
|
|
19
|
-
if (format === TelephoneNumberFieldOptionsFormatEnum.UK) {
|
|
20
|
-
return UK_ERROR_CODE
|
|
21
|
-
} else if (format === TelephoneNumberFieldOptionsFormatEnum.International) {
|
|
22
|
-
return INTERNATIONAL_ERROR_CODE
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return INVALID_ERROR_CODE
|
|
26
|
-
}
|
|
27
|
-
|
|
28
16
|
export const joi = JoiBase.extend({
|
|
29
17
|
type: 'string',
|
|
30
18
|
base: JoiBase.string(),
|
|
31
19
|
messages: {
|
|
32
|
-
[INVALID_ERROR_CODE]:
|
|
33
|
-
|
|
34
|
-
opts
|
|
35
|
-
) as JoiExpression,
|
|
36
|
-
[UK_ERROR_CODE]: JoiBase.expression(
|
|
37
|
-
'Enter {{lowerFirst(#label)}}, like 01632 960 001, 07700 900 982 or +44 808 157 0192',
|
|
38
|
-
opts
|
|
39
|
-
) as JoiExpression,
|
|
40
|
-
[INTERNATIONAL_ERROR_CODE]: JoiBase.expression(
|
|
41
|
-
'Enter {{lowerFirst(#label)}}, starting with + and the country code, for example +92333 1234567 or 00923331234567',
|
|
42
|
-
opts
|
|
43
|
-
) as JoiExpression
|
|
44
|
-
} as unknown as LanguageMessages,
|
|
20
|
+
[INVALID_ERROR_CODE]: messageTemplate.format
|
|
21
|
+
} as LanguageMessages,
|
|
45
22
|
rules: {
|
|
46
23
|
phoneNumber: {
|
|
47
24
|
method({
|
|
@@ -69,25 +46,24 @@ export const joi = JoiBase.extend({
|
|
|
69
46
|
const parsed = phoneUtil.parse(value, COUNTRY)
|
|
70
47
|
|
|
71
48
|
if (!phoneUtil.isValidNumber(parsed)) {
|
|
72
|
-
return error(
|
|
49
|
+
return error(INVALID_ERROR_CODE)
|
|
73
50
|
}
|
|
74
51
|
|
|
75
52
|
if (format) {
|
|
76
53
|
const isUK = isUKNumber(parsed)
|
|
77
54
|
|
|
78
|
-
if (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
format === TelephoneNumberFieldOptionsFormatEnum.International
|
|
55
|
+
if (
|
|
56
|
+
(!isUK && format === TelephoneNumberFieldOptionsFormatEnum.UK) ||
|
|
57
|
+
(isUK &&
|
|
58
|
+
format === TelephoneNumberFieldOptionsFormatEnum.International)
|
|
83
59
|
) {
|
|
84
|
-
return error(
|
|
60
|
+
return error(INVALID_ERROR_CODE)
|
|
85
61
|
}
|
|
86
62
|
}
|
|
87
63
|
|
|
88
64
|
return value
|
|
89
65
|
} catch {
|
|
90
|
-
return error(
|
|
66
|
+
return error(INVALID_ERROR_CODE)
|
|
91
67
|
}
|
|
92
68
|
}
|
|
93
69
|
}
|