@digigov/form 1.1.0 → 1.1.2-fd2cea11

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/CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # Change Log - @digigov/form
2
2
 
3
- This log was last generated on Mon, 29 Jan 2024 10:46:50 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 29 Jan 2024 17:45:11 GMT and should not be manually modified.
4
+
5
+ ## 1.1.1
6
+ Mon, 29 Jan 2024 17:45:11 GMT
7
+
8
+ _Version update only_
4
9
 
5
10
  ## 1.1.0
6
11
  Mon, 29 Jan 2024 10:46:50 GMT
@@ -55,6 +55,18 @@ Object.keys(_PhoneNumber).forEach(function (key) {
55
55
  }
56
56
  });
57
57
  });
58
+ var _LandlineNumber = require("@digigov/form/inputs/Input/__stories__/LandlineNumber");
59
+ Object.keys(_LandlineNumber).forEach(function (key) {
60
+ if (key === "default" || key === "__esModule") return;
61
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
62
+ if (key in exports && exports[key] === _LandlineNumber[key]) return;
63
+ Object.defineProperty(exports, key, {
64
+ enumerable: true,
65
+ get: function get() {
66
+ return _LandlineNumber[key];
67
+ }
68
+ });
69
+ });
58
70
  var _MobilePhone = require("@digigov/form/inputs/Input/__stories__/MobilePhone");
59
71
  Object.keys(_MobilePhone).forEach(function (key) {
60
72
  if (key === "default" || key === "__esModule") return;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports["default"] = exports.LandlineNumber = void 0;
9
+ var _react = _interopRequireDefault(require("react"));
10
+ var _form = _interopRequireWildcard(require("@digigov/form"));
11
+ var _Button = require("@digigov/ui/cjs/form/Button");
12
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
13
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
14
+ var _ref = /*#__PURE__*/_react["default"].createElement(_Button.Button, {
15
+ type: "submit"
16
+ }, "\u03A3\u03C5\u03BD\u03AD\u03C7\u03B5\u03B9\u03B1");
17
+ var LandlineNumber = exports.LandlineNumber = function LandlineNumber() {
18
+ return /*#__PURE__*/_react["default"].createElement(_form["default"], {
19
+ onSubmit: function onSubmit(data) {
20
+ console.log(data);
21
+ }
22
+ }, /*#__PURE__*/_react["default"].createElement(_form.Field, {
23
+ key: "phone-number",
24
+ name: "phone-number",
25
+ type: "phone_number",
26
+ label: {
27
+ primary: 'Σταθερό τηλέφωνο'
28
+ },
29
+ extra: {
30
+ countries: ['gr'],
31
+ phoneType: 'landline'
32
+ },
33
+ required: true
34
+ }), _ref);
35
+ };
36
+ var _default = exports["default"] = LandlineNumber;
@@ -26,6 +26,10 @@ var MobilePhone = exports.MobilePhone = function MobilePhone() {
26
26
  label: {
27
27
  primary: 'Κινητό τηλέφωνο'
28
28
  },
29
+ extra: {
30
+ countries: ['gr'],
31
+ phoneType: 'mobile'
32
+ },
29
33
  required: true
30
34
  }), _ref);
31
35
  };
@@ -24,7 +24,10 @@ var PhoneNumber = exports.PhoneNumber = function PhoneNumber() {
24
24
  name: "phone-number",
25
25
  type: "phone_number",
26
26
  label: {
27
- primary: 'Σταθερό τηλέφωνο'
27
+ primary: 'Tηλέφωνο'
28
+ },
29
+ extra: {
30
+ countries: ['gr']
28
31
  },
29
32
  required: true
30
33
  }), _ref);
@@ -1,87 +1,111 @@
1
1
  "use strict";
2
2
 
3
- var _typeof = require("@babel/runtime/helpers/typeof");
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.PHONE_NUMBER_VALIDATOR = exports.MOBILE_PHONE_VALIDATOR = void 0;
8
- exports.matchTypeOfPhoneNumber = matchTypeOfPhoneNumber;
8
+ exports.discoverPhoneType = discoverPhoneType;
9
9
  exports.validatePhoneNumber = validatePhoneNumber;
10
- var gPhoneNumber = _interopRequireWildcard(require("google-libphonenumber"));
11
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
12
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
13
- function validatePhoneNumber(phoneNumber) {
14
- var countries = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['gr'];
15
- var typeOfPhoneNumber = arguments.length > 2 ? arguments[2] : undefined;
16
- var phoneUtil = gPhoneNumber.PhoneNumberUtil.getInstance();
17
- if (!countries || countries.length === 0) {
18
- return true;
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
+ // add more countries from here libphonenumber-js/metadata.full.json
12
+ var countryPhoneData = {
13
+ "GR": ["30", "00", "5005000\\d{3}|8\\d{9,11}|(?:[269]\\d|70)\\d{8}", [10, 11, 12], [["(\\d{2})(\\d{4})(\\d{4})", "$1 $2 $3", ["21|7"]], ["(\\d{4})(\\d{6})", "$1 $2", ["2(?:2|3[2-57-9]|4[2-469]|5[2-59]|6[2-9]|7[2-69]|8[2-49])|5"]], ["(\\d{3})(\\d{3})(\\d{4})", "$1 $2 $3", ["[2689]"]], ["(\\d{3})(\\d{3,4})(\\d{5})", "$1 $2 $3", ["8"]]], 0, 0, 0, 0, 0, 0, [["2(?:1\\d\\d|2(?:2[1-46-9]|[36][1-8]|4[1-7]|5[1-4]|7[1-5]|[89][1-9])|3(?:1\\d|2[1-57]|[35][1-3]|4[13]|7[1-7]|8[124-6]|9[1-79])|4(?:1\\d|2[1-8]|3[1-4]|4[13-5]|6[1-578]|9[1-5])|5(?:1\\d|[29][1-4]|3[1-5]|4[124]|5[1-6])|6(?:1\\d|[269][1-6]|3[1245]|4[1-7]|5[13-9]|7[14]|8[1-5])|7(?:1\\d|2[1-5]|3[1-6]|4[1-7]|5[1-57]|6[135]|9[125-7])|8(?:1\\d|2[1-5]|[34][1-4]|9[1-57]))\\d{6}", [10]], ["68[57-9]\\d{7}|(?:69|94)\\d{8}", [10]], ["800\\d{7,9}"], ["90[19]\\d{7}", [10]], ["70\\d{8}", [10]], 0, ["5005000\\d{3}", [10]], 0, 0, ["8(?:0[16]|12|[27]5|50)\\d{7}", [10]]]]
14
+ };
15
+ function expandPhoneNumberStructure(compressed) {
16
+ var countries = Object.keys(compressed);
17
+ var expanded = {};
18
+ for (var _i = 0, _countries = countries; _i < _countries.length; _i++) {
19
+ var country = _countries[_i];
20
+ expanded[country] = {
21
+ fixedLine: {
22
+ possibleLengths: {
23
+ _national: compressed[country][3].map(String)
24
+ },
25
+ nationalNumberPattern: compressed[country][11][0][0]
26
+ },
27
+ mobile: {
28
+ nationalNumberPattern: compressed[country][11][1][0]
29
+ },
30
+ tollFree: {
31
+ nationalNumberPattern: compressed[country][11][2][0]
32
+ },
33
+ premiumRate: {
34
+ nationalNumberPattern: compressed[country][11][3][0]
35
+ },
36
+ sharedCost: {
37
+ nationalNumberPattern: compressed[country][11][9][0]
38
+ },
39
+ personalNumber: {
40
+ nationalNumberPattern: compressed[country][11][4][0]
41
+ },
42
+ uan: {
43
+ nationalNumberPattern: compressed[country][11][6][0]
44
+ },
45
+ id: country,
46
+ countryCode: compressed[country][0],
47
+ internationalPrefix: compressed[country][1]
48
+ };
19
49
  }
20
- return countries.some(function (country) {
21
- try {
22
- var phone = phoneUtil.parse(phoneNumber, country.toUpperCase());
23
- if (phoneUtil.isValidNumber(phone)) {
24
- if (typeOfPhoneNumber) {
25
- if (matchTypeOfPhoneNumber(phone, typeOfPhoneNumber, phoneUtil)) {
26
- return true;
27
- } else {
28
- return false;
29
- }
30
- } else {
31
- return true;
32
- }
33
- }
34
- return false;
35
- } catch (error) {
36
- console.error(error);
37
- return false;
38
- }
39
- });
50
+ return expanded;
40
51
  }
41
- var phoneNumberTypes = {
42
- 0: 'landline',
43
- 1: 'mobile',
44
- 2: 'landline_or_mobile'
45
- };
46
- function matchTypeOfPhoneNumber(phone, type, phoneUtil) {
47
- try {
48
- var phoneNumberType = phoneUtil.getNumberType(phone);
49
- var numberType = phoneNumberTypes[phoneNumberType];
50
- if (numberType === 'landline_or_mobile' || numberType === type) {
51
- return true;
52
- } else {
53
- return false;
52
+ var PHONENUMBER_SPEC = expandPhoneNumberStructure(countryPhoneData);
53
+ function discoverPhoneType(phoneNumber, config) {
54
+ var cleanNumber = phoneNumber.replace(/\D/g, "").replace(/\s/g, "").replace(/^\+/, "").replace(new RegExp("^" + config.internationalPrefix, ""), "").replace(new RegExp("^" + config.countryCode, ""), "");
55
+ var categories = {
56
+ "landline": config.fixedLine,
57
+ mobile: config.mobile,
58
+ "toll-free": config.tollFree,
59
+ "premium-rate": config.premiumRate
60
+ };
61
+ for (var _i2 = 0, _Object$entries = Object.entries(categories); _i2 < _Object$entries.length; _i2++) {
62
+ var _Object$entries$_i = (0, _slicedToArray2["default"])(_Object$entries[_i2], 2),
63
+ categoryName = _Object$entries$_i[0],
64
+ categoryDetails = _Object$entries$_i[1];
65
+ var pattern = new RegExp("^(" + categoryDetails.nationalNumberPattern.replace(/\s/g, "") + ")$", "");
66
+ if (cleanNumber.match(pattern)) {
67
+ return categoryName; // Returns the category name if the number matches the pattern
54
68
  }
55
- } catch (error) {
56
- console.error(error);
57
- return false;
58
69
  }
70
+
71
+ // If no category matches, return 'Unknown'
72
+ return "unknown";
59
73
  }
60
- function validateMobile(value) {
61
- var phoneUtil = gPhoneNumber.PhoneNumberUtil.getInstance();
62
- var origValue = value;
63
- // probably catch all the cases with a regex instead of gphonenumber
64
- if (!value.match(/^((\+|00){0,1}\d{1,3}[- ]?)?\d{10}$/)) {
65
- return false;
74
+ function getNumberType(phoneNumber, country) {
75
+ var spec = PHONENUMBER_SPEC[country.toUpperCase()];
76
+ if (!spec) {
77
+ throw new Error("Country ".concat(country, " is not supported"));
66
78
  }
67
- try {
68
- var phone;
69
- try {
70
- phone = phoneUtil.parse(value);
71
- } catch (err) {
72
- try {
73
- value = '+' + value;
74
- phone = phoneUtil.parse(value);
75
- } catch (err) {
76
- value = '+30' + origValue;
77
- phone = phoneUtil.parse(value);
78
- }
79
+ var type = discoverPhoneType(phoneNumber, spec);
80
+ return type;
81
+ }
82
+ function isPhoneNumberValid(phoneNumber, countries) {
83
+ var types = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ['mobile', 'landline'];
84
+ return countries.some(function (country) {
85
+ var numberType = getNumberType(phoneNumber, country);
86
+ if (numberType && types.includes(numberType)) {
87
+ return true;
79
88
  }
80
- return phoneUtil.isValidNumber(phone);
81
- } catch (err) {
82
- console.error(err);
83
89
  return false;
90
+ });
91
+ }
92
+ function isNumberOfType(phoneNumber, country, type) {
93
+ var numberType = getNumberType(phoneNumber, country);
94
+ if (numberType === type) {
95
+ return true;
96
+ }
97
+ return false;
98
+ }
99
+ function validatePhoneNumber(phoneNumber) {
100
+ var countries = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['gr'];
101
+ var typeOfPhoneNumber = arguments.length > 2 ? arguments[2] : undefined;
102
+ if (!countries || countries.length === 0) {
103
+ return true;
84
104
  }
105
+ return isPhoneNumberValid(phoneNumber, countries, typeOfPhoneNumber ? [typeOfPhoneNumber] : undefined);
106
+ }
107
+ function validateMobile(value) {
108
+ return isNumberOfType(value, 'gr', 'mobile');
85
109
  }
86
110
  var MOBILE_PHONE_VALIDATOR = exports.MOBILE_PHONE_VALIDATOR = {
87
111
  name: 'mobile-phone-validator',
@@ -95,7 +119,7 @@ var MOBILE_PHONE_VALIDATOR = exports.MOBILE_PHONE_VALIDATOR = {
95
119
  };
96
120
  var PHONE_NUMBER_VALIDATOR = exports.PHONE_NUMBER_VALIDATOR = function PHONE_NUMBER_VALIDATOR(field) {
97
121
  var _field$extra, _field$extra2;
98
- var countryCode = field === null || field === void 0 ? void 0 : (_field$extra = field.extra) === null || _field$extra === void 0 ? void 0 : _field$extra.countries;
122
+ var countryCodes = field === null || field === void 0 ? void 0 : (_field$extra = field.extra) === null || _field$extra === void 0 ? void 0 : _field$extra.countries;
99
123
  var typeOfPhone = field === null || field === void 0 ? void 0 : (_field$extra2 = field.extra) === null || _field$extra2 === void 0 ? void 0 : _field$extra2.phoneType;
100
124
  return {
101
125
  name: 'phone-number-validator',
@@ -113,7 +137,7 @@ var PHONE_NUMBER_VALIDATOR = exports.PHONE_NUMBER_VALIDATOR = function PHONE_NUM
113
137
  if (!value) {
114
138
  return true;
115
139
  }
116
- return validatePhoneNumber(value, countryCode, typeOfPhone);
140
+ return validatePhoneNumber(value, countryCodes, typeOfPhone);
117
141
  }
118
142
  };
119
143
  };
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license Digigov v1.1.0
1
+ /** @license Digigov v1.1.2-fd2cea11
2
2
  *
3
3
  * This source code is licensed under the BSD-2-Clause license found in the
4
4
  * LICENSE file in the root directory of this source tree.
@@ -8,6 +8,7 @@ export * from '@digigov/form/inputs/Input/__stories__/Default';
8
8
  export * from '@digigov/form/inputs/Input/__stories__/Integer';
9
9
  export * from '@digigov/form/inputs/Input/__stories__/Boolean';
10
10
  export * from '@digigov/form/inputs/Input/__stories__/PhoneNumber';
11
+ export * from '@digigov/form/inputs/Input/__stories__/LandlineNumber';
11
12
  export * from '@digigov/form/inputs/Input/__stories__/MobilePhone';
12
13
  export * from '@digigov/form/inputs/Input/__stories__/AFM';
13
14
  export * from '@digigov/form/inputs/Input/__stories__/IBAN';
@@ -8,6 +8,7 @@ export * from "@digigov/form/inputs/Input/__stories__/Default";
8
8
  export * from "@digigov/form/inputs/Input/__stories__/Integer";
9
9
  export * from "@digigov/form/inputs/Input/__stories__/Boolean";
10
10
  export * from "@digigov/form/inputs/Input/__stories__/PhoneNumber";
11
+ export * from "@digigov/form/inputs/Input/__stories__/LandlineNumber";
11
12
  export * from "@digigov/form/inputs/Input/__stories__/MobilePhone";
12
13
  export * from "@digigov/form/inputs/Input/__stories__/AFM";
13
14
  export * from "@digigov/form/inputs/Input/__stories__/IBAN";
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import FormBuilder, { Field } from '@digigov/form';
3
+ import { Button } from '@digigov/ui/form/Button';
4
+ var _ref = /*#__PURE__*/React.createElement(Button, {
5
+ type: "submit"
6
+ }, "\u03A3\u03C5\u03BD\u03AD\u03C7\u03B5\u03B9\u03B1");
7
+ export var LandlineNumber = function LandlineNumber() {
8
+ return /*#__PURE__*/React.createElement(FormBuilder, {
9
+ onSubmit: function onSubmit(data) {
10
+ console.log(data);
11
+ }
12
+ }, /*#__PURE__*/React.createElement(Field, {
13
+ key: "phone-number",
14
+ name: "phone-number",
15
+ type: "phone_number",
16
+ label: {
17
+ primary: 'Σταθερό τηλέφωνο'
18
+ },
19
+ extra: {
20
+ countries: ['gr'],
21
+ phoneType: 'landline'
22
+ },
23
+ required: true
24
+ }), _ref);
25
+ };
26
+ export default LandlineNumber;
@@ -0,0 +1,6 @@
1
+ {
2
+ "sideEffects": false,
3
+ "module": "./index.js",
4
+ "types": "./index.d.ts",
5
+ "main": "../../../../cjs/inputs/Input/__stories__/LandlineNumber/index.js"
6
+ }
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ export declare const LandlineNumber: () => JSX.Element;
3
+ export default LandlineNumber;
@@ -16,6 +16,10 @@ export var MobilePhone = function MobilePhone() {
16
16
  label: {
17
17
  primary: 'Κινητό τηλέφωνο'
18
18
  },
19
+ extra: {
20
+ countries: ['gr'],
21
+ phoneType: 'mobile'
22
+ },
19
23
  required: true
20
24
  }), _ref);
21
25
  };
@@ -14,7 +14,10 @@ export var PhoneNumber = function PhoneNumber() {
14
14
  name: "phone-number",
15
15
  type: "phone_number",
16
16
  label: {
17
- primary: 'Σταθερό τηλέφωνο'
17
+ primary: 'Tηλέφωνο'
18
+ },
19
+ extra: {
20
+ countries: ['gr']
18
21
  },
19
22
  required: true
20
23
  }), _ref);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digigov/form",
3
- "version": "1.1.0",
3
+ "version": "1.1.2-fd2cea11",
4
4
  "description": "@digigov form builder",
5
5
  "author": "GRNET Developers <devs@lists.grnet.gr>",
6
6
  "license": "BSD-2-Clause",
@@ -12,15 +12,14 @@
12
12
  "dependencies": {
13
13
  "react-hook-form": "7.33.1",
14
14
  "yup": "0.32.11",
15
- "google-libphonenumber": "3.2.8",
16
15
  "dayjs": "1.10.4",
17
16
  "@hookform/resolvers": "2.9.6",
18
17
  "publint": "0.1.8",
19
- "@digigov/react-icons": "1.1.0"
18
+ "@digigov/react-icons": "1.1.2-fd2cea11"
20
19
  },
21
20
  "peerDependencies": {
22
- "@digigov/ui": "1.1.0",
23
- "@digigov/react-core": "1.1.0",
21
+ "@digigov/ui": "1.1.2-fd2cea11",
22
+ "@digigov/react-core": "1.2.0-fd2cea11",
24
23
  "clsx": "1.1.1",
25
24
  "react": "^16.8.0 || ^17.0.0",
26
25
  "react-dom": "^16.8.0 || ^17.0.0"
@@ -8,6 +8,7 @@ export * from '@digigov/form/inputs/Input/__stories__/Default';
8
8
  export * from '@digigov/form/inputs/Input/__stories__/Integer';
9
9
  export * from '@digigov/form/inputs/Input/__stories__/Boolean';
10
10
  export * from '@digigov/form/inputs/Input/__stories__/PhoneNumber';
11
+ export * from '@digigov/form/inputs/Input/__stories__/LandlineNumber';
11
12
  export * from '@digigov/form/inputs/Input/__stories__/MobilePhone';
12
13
  export * from '@digigov/form/inputs/Input/__stories__/AFM';
13
14
  export * from '@digigov/form/inputs/Input/__stories__/IBAN';
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import FormBuilder, { Field } from '@digigov/form';
3
+ import { Button } from '@digigov/ui/form/Button';
4
+
5
+ export const LandlineNumber = () => (
6
+ <FormBuilder
7
+ onSubmit={(data) => {
8
+ console.log(data);
9
+ }}
10
+ >
11
+ <Field
12
+ key="phone-number"
13
+ name="phone-number"
14
+ type="phone_number"
15
+ label={{
16
+ primary: 'Σταθερό τηλέφωνο',
17
+ }}
18
+ extra={{
19
+ countries: ['gr'],
20
+ phoneType:'landline',
21
+ }}
22
+ required
23
+ />
24
+ <Button type="submit">Συνέχεια</Button>
25
+ </FormBuilder>
26
+ );
27
+ export default LandlineNumber;
@@ -15,6 +15,10 @@ export const MobilePhone = () => (
15
15
  label={{
16
16
  primary: 'Κινητό τηλέφωνο',
17
17
  }}
18
+ extra={{
19
+ countries: ['gr'],
20
+ phoneType: 'mobile',
21
+ }}
18
22
  required
19
23
  />
20
24
  <Button type="submit">Συνέχεια</Button>
@@ -13,7 +13,10 @@ export const PhoneNumber = () => (
13
13
  name="phone-number"
14
14
  type="phone_number"
15
15
  label={{
16
- primary: 'Σταθερό τηλέφωνο',
16
+ primary: 'Tηλέφωνο',
17
+ }}
18
+ extra={{
19
+ countries: ['gr'],
17
20
  }}
18
21
  required
19
22
  />
@@ -1,87 +1,167 @@
1
- import * as gPhoneNumber from 'google-libphonenumber';
2
1
  import { FieldSpec } from '@digigov/form/types';
3
2
  import { ValidatorSchema } from '@digigov/form/validators/types';
4
3
 
5
4
  export type PhoneNumberType = 'landline' | 'mobile' | null;
5
+ // add more countries from here libphonenumber-js/metadata.full.json
6
+ const countryPhoneData = {
7
+ "GR": [
8
+ "30",
9
+ "00",
10
+ "5005000\\d{3}|8\\d{9,11}|(?:[269]\\d|70)\\d{8}",
11
+ [10, 11, 12],
12
+ [
13
+ ["(\\d{2})(\\d{4})(\\d{4})", "$1 $2 $3", ["21|7"]],
14
+ [
15
+ "(\\d{4})(\\d{6})",
16
+ "$1 $2",
17
+ ["2(?:2|3[2-57-9]|4[2-469]|5[2-59]|6[2-9]|7[2-69]|8[2-49])|5"]
18
+ ],
19
+ ["(\\d{3})(\\d{3})(\\d{4})", "$1 $2 $3", ["[2689]"]],
20
+ ["(\\d{3})(\\d{3,4})(\\d{5})", "$1 $2 $3", ["8"]]
21
+ ],
22
+ 0,
23
+ 0,
24
+ 0,
25
+ 0,
26
+ 0,
27
+ 0,
28
+ [
29
+ [
30
+ "2(?:1\\d\\d|2(?:2[1-46-9]|[36][1-8]|4[1-7]|5[1-4]|7[1-5]|[89][1-9])|3(?:1\\d|2[1-57]|[35][1-3]|4[13]|7[1-7]|8[124-6]|9[1-79])|4(?:1\\d|2[1-8]|3[1-4]|4[13-5]|6[1-578]|9[1-5])|5(?:1\\d|[29][1-4]|3[1-5]|4[124]|5[1-6])|6(?:1\\d|[269][1-6]|3[1245]|4[1-7]|5[13-9]|7[14]|8[1-5])|7(?:1\\d|2[1-5]|3[1-6]|4[1-7]|5[1-57]|6[135]|9[125-7])|8(?:1\\d|2[1-5]|[34][1-4]|9[1-57]))\\d{6}",
31
+ [10]
32
+ ],
33
+ ["68[57-9]\\d{7}|(?:69|94)\\d{8}", [10]],
34
+ ["800\\d{7,9}"],
35
+ ["90[19]\\d{7}", [10]],
36
+ ["70\\d{8}", [10]],
37
+ 0,
38
+ ["5005000\\d{3}", [10]],
39
+ 0,
40
+ 0,
41
+ ["8(?:0[16]|12|[27]5|50)\\d{7}", [10]]
42
+ ]
43
+ ]
44
+ }
6
45
 
7
- export function validatePhoneNumber(
46
+ function expandPhoneNumberStructure(compressed) {
47
+ const countries = Object.keys(compressed);
48
+ const expanded: any = {}
49
+ for (const country of countries) {
50
+ expanded[country] = {
51
+ fixedLine: {
52
+ possibleLengths: {
53
+ _national:
54
+ compressed[country][3].map(
55
+ String
56
+ ),
57
+ },
58
+ nationalNumberPattern:
59
+ compressed[country][11][0][0],
60
+ },
61
+ mobile: {
62
+ nationalNumberPattern:
63
+ compressed[country][11][1][0],
64
+ },
65
+ tollFree: {
66
+ nationalNumberPattern:
67
+ compressed[country][11][2][0],
68
+ },
69
+ premiumRate: {
70
+ nationalNumberPattern:
71
+ compressed[country][11][3][0],
72
+ },
73
+ sharedCost: {
74
+ nationalNumberPattern:
75
+ compressed[country][11][9][0],
76
+ },
77
+ personalNumber: {
78
+ nationalNumberPattern:
79
+ compressed[country][11][4][0],
80
+ },
81
+ uan: {
82
+ nationalNumberPattern:
83
+ compressed[country][11][6][0],
84
+ },
85
+ id: country,
86
+ countryCode:
87
+ compressed[country][0],
88
+ internationalPrefix:
89
+ compressed[country][1],
90
+
91
+ }
92
+ }
93
+ return expanded;
94
+ }
95
+ const PHONENUMBER_SPEC = expandPhoneNumberStructure(countryPhoneData);
96
+ export function discoverPhoneType(
8
97
  phoneNumber: string,
9
- countries: Array<string> = ['gr'],
10
- typeOfPhoneNumber: PhoneNumberType
11
- ): boolean {
12
- const phoneUtil = gPhoneNumber.PhoneNumberUtil.getInstance();
13
- if (!countries || countries.length === 0) {
14
- return true;
98
+ config: any
99
+ ): string {
100
+ const cleanNumber = phoneNumber
101
+ .replace(/\D/g, "")
102
+ .replace(/\s/g, "")
103
+ .replace(/^\+/, "")
104
+ .replace(new RegExp("^" + config.internationalPrefix, ""), "")
105
+ .replace(new RegExp("^" + config.countryCode, ""), "");
106
+ const categories = {
107
+ "landline": config.fixedLine,
108
+ mobile: config.mobile,
109
+ "toll-free": config.tollFree,
110
+ "premium-rate": config.premiumRate,
111
+ };
112
+
113
+ for (const [categoryName, categoryDetails] of Object.entries(categories)) {
114
+ const pattern = new RegExp(
115
+ "^(" + categoryDetails.nationalNumberPattern.replace(/\s/g, "") + ")$",
116
+ ""
117
+ );
118
+ if (cleanNumber.match(pattern)) {
119
+ return categoryName; // Returns the category name if the number matches the pattern
120
+ }
15
121
  }
122
+
123
+ // If no category matches, return 'Unknown'
124
+ return "unknown";
125
+ }
126
+ function getNumberType(phoneNumber: string, country: string) {
127
+ const spec = PHONENUMBER_SPEC[country.toUpperCase()];
128
+ if(!spec) {
129
+ throw new Error(`Country ${country} is not supported`);
130
+ }
131
+ const type = discoverPhoneType(phoneNumber, spec);
132
+ return type;
133
+ }
134
+
135
+ function isPhoneNumberValid(phoneNumber: string, countries: string[], types=['mobile', 'landline']) {
16
136
  return countries.some((country) => {
17
- try {
18
- const phone = phoneUtil.parse(phoneNumber, country.toUpperCase());
19
- if (phoneUtil.isValidNumber(phone)) {
20
- if (typeOfPhoneNumber) {
21
- if (matchTypeOfPhoneNumber(phone, typeOfPhoneNumber, phoneUtil)) {
22
- return true;
23
- } else {
24
- return false;
25
- }
26
- } else {
27
- return true;
28
- }
29
- }
30
- return false;
31
- } catch (error) {
32
- console.error(error);
33
- return false;
137
+ const numberType = getNumberType(phoneNumber, country);
138
+ if (numberType && types.includes(numberType)) {
139
+ return true
34
140
  }
35
- });
141
+ return false
142
+ })
36
143
  }
37
- const phoneNumberTypes = {
38
- 0: 'landline',
39
- 1: 'mobile',
40
- 2: 'landline_or_mobile',
41
- };
42
- export function matchTypeOfPhoneNumber(
43
- phone: any,
44
- type: string,
45
- phoneUtil: any
144
+ function isNumberOfType(phoneNumber: string, country: string, type: string) {
145
+ const numberType = getNumberType(phoneNumber, country);
146
+ if (numberType === type) {
147
+ return true
148
+ }
149
+ return false
150
+ }
151
+ export function validatePhoneNumber(
152
+ phoneNumber: string,
153
+ countries: Array<string> = ['gr'],
154
+ typeOfPhoneNumber?: PhoneNumberType
46
155
  ): boolean {
47
- try {
48
- const phoneNumberType = phoneUtil.getNumberType(phone);
49
- const numberType = phoneNumberTypes[phoneNumberType];
50
- if (numberType === 'landline_or_mobile' || numberType === type) {
51
- return true;
52
- } else {
53
- return false;
54
- }
55
- } catch (error) {
56
- console.error(error);
57
- return false;
156
+ if (!countries || countries.length === 0) {
157
+ return true;
58
158
  }
159
+ return isPhoneNumberValid(phoneNumber, countries, typeOfPhoneNumber? [typeOfPhoneNumber] : undefined);
59
160
  }
161
+
162
+
60
163
  function validateMobile(value): boolean {
61
- const phoneUtil = gPhoneNumber.PhoneNumberUtil.getInstance();
62
- const origValue = value;
63
- // probably catch all the cases with a regex instead of gphonenumber
64
- if (!value.match(/^((\+|00){0,1}\d{1,3}[- ]?)?\d{10}$/)) {
65
- return false;
66
- }
67
- try {
68
- let phone;
69
- try {
70
- phone = phoneUtil.parse(value);
71
- } catch (err) {
72
- try {
73
- value = '+' + value;
74
- phone = phoneUtil.parse(value);
75
- } catch (err) {
76
- value = '+30' + origValue;
77
- phone = phoneUtil.parse(value);
78
- }
79
- }
80
- return phoneUtil.isValidNumber(phone);
81
- } catch (err) {
82
- console.error(err);
83
- return false;
84
- }
164
+ return isNumberOfType(value, 'gr','mobile');
85
165
  }
86
166
 
87
167
  export const MOBILE_PHONE_VALIDATOR = {
@@ -96,7 +176,7 @@ export const MOBILE_PHONE_VALIDATOR = {
96
176
  };
97
177
 
98
178
  export const PHONE_NUMBER_VALIDATOR = (field: FieldSpec): ValidatorSchema => {
99
- const countryCode = field?.extra?.countries;
179
+ const countryCodes = field?.extra?.countries;
100
180
  const typeOfPhone: PhoneNumberType | null = field?.extra?.phoneType;
101
181
  return {
102
182
  name: 'phone-number-validator',
@@ -114,7 +194,7 @@ export const PHONE_NUMBER_VALIDATOR = (field: FieldSpec): ValidatorSchema => {
114
194
  if (!value) {
115
195
  return true;
116
196
  }
117
- return validatePhoneNumber(value, countryCode, typeOfPhone);
197
+ return validatePhoneNumber(value, countryCodes, typeOfPhone);
118
198
  },
119
199
  };
120
200
  };
@@ -1,76 +1,102 @@
1
- import * as gPhoneNumber from 'google-libphonenumber';
2
- export function validatePhoneNumber(phoneNumber) {
3
- var countries = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['gr'];
4
- var typeOfPhoneNumber = arguments.length > 2 ? arguments[2] : undefined;
5
- var phoneUtil = gPhoneNumber.PhoneNumberUtil.getInstance();
6
- if (!countries || countries.length === 0) {
7
- return true;
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ // add more countries from here libphonenumber-js/metadata.full.json
3
+ var countryPhoneData = {
4
+ "GR": ["30", "00", "5005000\\d{3}|8\\d{9,11}|(?:[269]\\d|70)\\d{8}", [10, 11, 12], [["(\\d{2})(\\d{4})(\\d{4})", "$1 $2 $3", ["21|7"]], ["(\\d{4})(\\d{6})", "$1 $2", ["2(?:2|3[2-57-9]|4[2-469]|5[2-59]|6[2-9]|7[2-69]|8[2-49])|5"]], ["(\\d{3})(\\d{3})(\\d{4})", "$1 $2 $3", ["[2689]"]], ["(\\d{3})(\\d{3,4})(\\d{5})", "$1 $2 $3", ["8"]]], 0, 0, 0, 0, 0, 0, [["2(?:1\\d\\d|2(?:2[1-46-9]|[36][1-8]|4[1-7]|5[1-4]|7[1-5]|[89][1-9])|3(?:1\\d|2[1-57]|[35][1-3]|4[13]|7[1-7]|8[124-6]|9[1-79])|4(?:1\\d|2[1-8]|3[1-4]|4[13-5]|6[1-578]|9[1-5])|5(?:1\\d|[29][1-4]|3[1-5]|4[124]|5[1-6])|6(?:1\\d|[269][1-6]|3[1245]|4[1-7]|5[13-9]|7[14]|8[1-5])|7(?:1\\d|2[1-5]|3[1-6]|4[1-7]|5[1-57]|6[135]|9[125-7])|8(?:1\\d|2[1-5]|[34][1-4]|9[1-57]))\\d{6}", [10]], ["68[57-9]\\d{7}|(?:69|94)\\d{8}", [10]], ["800\\d{7,9}"], ["90[19]\\d{7}", [10]], ["70\\d{8}", [10]], 0, ["5005000\\d{3}", [10]], 0, 0, ["8(?:0[16]|12|[27]5|50)\\d{7}", [10]]]]
5
+ };
6
+ function expandPhoneNumberStructure(compressed) {
7
+ var countries = Object.keys(compressed);
8
+ var expanded = {};
9
+ for (var _i = 0, _countries = countries; _i < _countries.length; _i++) {
10
+ var country = _countries[_i];
11
+ expanded[country] = {
12
+ fixedLine: {
13
+ possibleLengths: {
14
+ _national: compressed[country][3].map(String)
15
+ },
16
+ nationalNumberPattern: compressed[country][11][0][0]
17
+ },
18
+ mobile: {
19
+ nationalNumberPattern: compressed[country][11][1][0]
20
+ },
21
+ tollFree: {
22
+ nationalNumberPattern: compressed[country][11][2][0]
23
+ },
24
+ premiumRate: {
25
+ nationalNumberPattern: compressed[country][11][3][0]
26
+ },
27
+ sharedCost: {
28
+ nationalNumberPattern: compressed[country][11][9][0]
29
+ },
30
+ personalNumber: {
31
+ nationalNumberPattern: compressed[country][11][4][0]
32
+ },
33
+ uan: {
34
+ nationalNumberPattern: compressed[country][11][6][0]
35
+ },
36
+ id: country,
37
+ countryCode: compressed[country][0],
38
+ internationalPrefix: compressed[country][1]
39
+ };
8
40
  }
9
- return countries.some(function (country) {
10
- try {
11
- var phone = phoneUtil.parse(phoneNumber, country.toUpperCase());
12
- if (phoneUtil.isValidNumber(phone)) {
13
- if (typeOfPhoneNumber) {
14
- if (matchTypeOfPhoneNumber(phone, typeOfPhoneNumber, phoneUtil)) {
15
- return true;
16
- } else {
17
- return false;
18
- }
19
- } else {
20
- return true;
21
- }
22
- }
23
- return false;
24
- } catch (error) {
25
- console.error(error);
26
- return false;
27
- }
28
- });
41
+ return expanded;
29
42
  }
30
- var phoneNumberTypes = {
31
- 0: 'landline',
32
- 1: 'mobile',
33
- 2: 'landline_or_mobile'
34
- };
35
- export function matchTypeOfPhoneNumber(phone, type, phoneUtil) {
36
- try {
37
- var phoneNumberType = phoneUtil.getNumberType(phone);
38
- var numberType = phoneNumberTypes[phoneNumberType];
39
- if (numberType === 'landline_or_mobile' || numberType === type) {
40
- return true;
41
- } else {
42
- return false;
43
+ var PHONENUMBER_SPEC = expandPhoneNumberStructure(countryPhoneData);
44
+ export function discoverPhoneType(phoneNumber, config) {
45
+ var cleanNumber = phoneNumber.replace(/\D/g, "").replace(/\s/g, "").replace(/^\+/, "").replace(new RegExp("^" + config.internationalPrefix, ""), "").replace(new RegExp("^" + config.countryCode, ""), "");
46
+ var categories = {
47
+ "landline": config.fixedLine,
48
+ mobile: config.mobile,
49
+ "toll-free": config.tollFree,
50
+ "premium-rate": config.premiumRate
51
+ };
52
+ for (var _i2 = 0, _Object$entries = Object.entries(categories); _i2 < _Object$entries.length; _i2++) {
53
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i2], 2),
54
+ categoryName = _Object$entries$_i[0],
55
+ categoryDetails = _Object$entries$_i[1];
56
+ var pattern = new RegExp("^(" + categoryDetails.nationalNumberPattern.replace(/\s/g, "") + ")$", "");
57
+ if (cleanNumber.match(pattern)) {
58
+ return categoryName; // Returns the category name if the number matches the pattern
43
59
  }
44
- } catch (error) {
45
- console.error(error);
46
- return false;
47
60
  }
61
+
62
+ // If no category matches, return 'Unknown'
63
+ return "unknown";
48
64
  }
49
- function validateMobile(value) {
50
- var phoneUtil = gPhoneNumber.PhoneNumberUtil.getInstance();
51
- var origValue = value;
52
- // probably catch all the cases with a regex instead of gphonenumber
53
- if (!value.match(/^((\+|00){0,1}\d{1,3}[- ]?)?\d{10}$/)) {
54
- return false;
65
+ function getNumberType(phoneNumber, country) {
66
+ var spec = PHONENUMBER_SPEC[country.toUpperCase()];
67
+ if (!spec) {
68
+ throw new Error("Country ".concat(country, " is not supported"));
55
69
  }
56
- try {
57
- var phone;
58
- try {
59
- phone = phoneUtil.parse(value);
60
- } catch (err) {
61
- try {
62
- value = '+' + value;
63
- phone = phoneUtil.parse(value);
64
- } catch (err) {
65
- value = '+30' + origValue;
66
- phone = phoneUtil.parse(value);
67
- }
70
+ var type = discoverPhoneType(phoneNumber, spec);
71
+ return type;
72
+ }
73
+ function isPhoneNumberValid(phoneNumber, countries) {
74
+ var types = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ['mobile', 'landline'];
75
+ return countries.some(function (country) {
76
+ var numberType = getNumberType(phoneNumber, country);
77
+ if (numberType && types.includes(numberType)) {
78
+ return true;
68
79
  }
69
- return phoneUtil.isValidNumber(phone);
70
- } catch (err) {
71
- console.error(err);
72
80
  return false;
81
+ });
82
+ }
83
+ function isNumberOfType(phoneNumber, country, type) {
84
+ var numberType = getNumberType(phoneNumber, country);
85
+ if (numberType === type) {
86
+ return true;
87
+ }
88
+ return false;
89
+ }
90
+ export function validatePhoneNumber(phoneNumber) {
91
+ var countries = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['gr'];
92
+ var typeOfPhoneNumber = arguments.length > 2 ? arguments[2] : undefined;
93
+ if (!countries || countries.length === 0) {
94
+ return true;
73
95
  }
96
+ return isPhoneNumberValid(phoneNumber, countries, typeOfPhoneNumber ? [typeOfPhoneNumber] : undefined);
97
+ }
98
+ function validateMobile(value) {
99
+ return isNumberOfType(value, 'gr', 'mobile');
74
100
  }
75
101
  export var MOBILE_PHONE_VALIDATOR = {
76
102
  name: 'mobile-phone-validator',
@@ -84,7 +110,7 @@ export var MOBILE_PHONE_VALIDATOR = {
84
110
  };
85
111
  export var PHONE_NUMBER_VALIDATOR = function PHONE_NUMBER_VALIDATOR(field) {
86
112
  var _field$extra, _field$extra2;
87
- var countryCode = field === null || field === void 0 ? void 0 : (_field$extra = field.extra) === null || _field$extra === void 0 ? void 0 : _field$extra.countries;
113
+ var countryCodes = field === null || field === void 0 ? void 0 : (_field$extra = field.extra) === null || _field$extra === void 0 ? void 0 : _field$extra.countries;
88
114
  var typeOfPhone = field === null || field === void 0 ? void 0 : (_field$extra2 = field.extra) === null || _field$extra2 === void 0 ? void 0 : _field$extra2.phoneType;
89
115
  return {
90
116
  name: 'phone-number-validator',
@@ -102,7 +128,7 @@ export var PHONE_NUMBER_VALIDATOR = function PHONE_NUMBER_VALIDATOR(field) {
102
128
  if (!value) {
103
129
  return true;
104
130
  }
105
- return validatePhoneNumber(value, countryCode, typeOfPhone);
131
+ return validatePhoneNumber(value, countryCodes, typeOfPhone);
106
132
  }
107
133
  };
108
134
  };
@@ -1,8 +1,8 @@
1
1
  import { FieldSpec } from '@digigov/form/types';
2
2
  import { ValidatorSchema } from '@digigov/form/validators/types';
3
3
  export type PhoneNumberType = 'landline' | 'mobile' | null;
4
- export declare function validatePhoneNumber(phoneNumber: string, countries: string[] | undefined, typeOfPhoneNumber: PhoneNumberType): boolean;
5
- export declare function matchTypeOfPhoneNumber(phone: any, type: string, phoneUtil: any): boolean;
4
+ export declare function discoverPhoneType(phoneNumber: string, config: any): string;
5
+ export declare function validatePhoneNumber(phoneNumber: string, countries?: Array<string>, typeOfPhoneNumber?: PhoneNumberType): boolean;
6
6
  export declare const MOBILE_PHONE_VALIDATOR: {
7
7
  name: string;
8
8
  message: string;