@digigov/form 1.1.5-496927f3 → 1.2.0-01ea6f24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/Questions/__snapshots__/index.spec.tsx.snap +30 -30
  2. package/cjs/Questions/__snapshots__/index.spec.tsx.snap +30 -30
  3. package/cjs/inputs/ImageInput/index.js +2 -2
  4. package/cjs/inputs/Input/Input.stories/index.js +12 -0
  5. package/cjs/inputs/Input/__stories__/LandlineNumber/index.js +36 -0
  6. package/cjs/inputs/Input/__stories__/MobilePhone/index.js +4 -0
  7. package/cjs/inputs/Input/__stories__/PhoneNumber/index.js +4 -1
  8. package/cjs/lazy/index.js +517 -0
  9. package/cjs/validators/utils/phone/index.js +94 -70
  10. package/index.js +1 -1
  11. package/inputs/ImageInput/index.js +2 -2
  12. package/inputs/Input/Input.stories/index.js +1 -0
  13. package/inputs/Input/Input.stories.d.ts +1 -0
  14. package/inputs/Input/__stories__/LandlineNumber/index.js +26 -0
  15. package/inputs/Input/__stories__/LandlineNumber/package.json +6 -0
  16. package/inputs/Input/__stories__/LandlineNumber.d.ts +3 -0
  17. package/inputs/Input/__stories__/MobilePhone/index.js +4 -0
  18. package/inputs/Input/__stories__/PhoneNumber/index.js +4 -1
  19. package/lazy/index.js +395 -0
  20. package/lazy/package.json +6 -0
  21. package/lazy.d.ts +69 -0
  22. package/package.json +4 -5
  23. package/src/Questions/__snapshots__/index.spec.tsx.snap +30 -30
  24. package/src/inputs/ImageInput/index.tsx +2 -2
  25. package/src/inputs/Input/Input.stories.js +1 -0
  26. package/src/inputs/Input/__stories__/LandlineNumber.tsx +27 -0
  27. package/src/inputs/Input/__stories__/MobilePhone.tsx +4 -0
  28. package/src/inputs/Input/__stories__/PhoneNumber.tsx +4 -1
  29. package/src/lazy.js +60 -0
  30. package/src/validators/utils/phone.ts +152 -72
  31. package/validators/utils/phone/index.js +92 -66
  32. package/validators/utils/phone.d.ts +2 -2
@@ -55,13 +55,13 @@ exports[`renders the Questions 1`] = `
55
55
  <ForwardRef(BackLink)>
56
56
  <ForwardRef(Base)
57
57
  as="a"
58
- className="govgr-back-link"
58
+ className="ds-back-link"
59
59
  onClick={[Function]}
60
60
  printHidden={true}
61
61
  tabIndex={0}
62
62
  >
63
63
  <a
64
- className="govgr-back-link govgr-print-hidden"
64
+ className="ds-back-link ds-print-hidden"
65
65
  onClick={[Function]}
66
66
  tabIndex={0}
67
67
  >
@@ -73,18 +73,18 @@ exports[`renders the Questions 1`] = `
73
73
  icon="caret"
74
74
  >
75
75
  <ForwardRef(SvgIcon)
76
- className="govgr-svg-icon--caret"
76
+ className="ds-svg-icon--caret"
77
77
  >
78
78
  <ForwardRef(Base)
79
79
  aria-hidden="true"
80
80
  as="svg"
81
- className="govgr-svg-icon--caret govgr-svg-icon"
81
+ className="ds-svg-icon--caret ds-svg-icon"
82
82
  focusable="false"
83
83
  viewBox="0 0 24 24"
84
84
  >
85
85
  <svg
86
86
  aria-hidden="true"
87
- className="govgr-svg-icon--caret govgr-svg-icon"
87
+ className="ds-svg-icon--caret ds-svg-icon"
88
88
  focusable="false"
89
89
  viewBox="0 0 24 24"
90
90
  >
@@ -108,19 +108,19 @@ exports[`renders the Questions 1`] = `
108
108
  <ForwardRef(PageTitleContainer)>
109
109
  <ForwardRef(Base)
110
110
  as="div"
111
- className="govgr-page-title"
111
+ className="ds-page-title"
112
112
  >
113
113
  <div
114
- className="govgr-page-title"
114
+ className="ds-page-title"
115
115
  >
116
116
  <ForwardRef(PageTitleCaption)>
117
117
  <ForwardRef(HeadingCaption)>
118
118
  <ForwardRef(Base)
119
119
  as="span"
120
- className="govgr-caption-lg"
120
+ className="ds-caption-lg"
121
121
  >
122
122
  <span
123
- className="govgr-caption-lg"
123
+ className="ds-caption-lg"
124
124
  >
125
125
  intro.caption
126
126
  </span>
@@ -132,10 +132,10 @@ exports[`renders the Questions 1`] = `
132
132
  <ForwardRef(Heading)>
133
133
  <ForwardRef(Base)
134
134
  as="h1"
135
- className="govgr-heading-xl"
135
+ className="ds-heading-xl"
136
136
  >
137
137
  <h1
138
- className="govgr-heading-xl"
138
+ className="ds-heading-xl"
139
139
  >
140
140
  intro.title
141
141
  </h1>
@@ -152,10 +152,10 @@ exports[`renders the Questions 1`] = `
152
152
  <ForwardRef(Paragraph)>
153
153
  <ForwardRef(Base)
154
154
  as="p"
155
- className="govgr-body"
155
+ className="ds-body"
156
156
  >
157
157
  <p
158
- className="govgr-body"
158
+ className="ds-body"
159
159
  >
160
160
  This is the intro
161
161
  </p>
@@ -211,11 +211,11 @@ exports[`renders the Questions 1`] = `
211
211
  >
212
212
  <ForwardRef(Base)
213
213
  as="form"
214
- className="govgr-form"
214
+ className="ds-form"
215
215
  onSubmit={[Function]}
216
216
  >
217
217
  <form
218
- className="govgr-form"
218
+ className="ds-form"
219
219
  onSubmit={[Function]}
220
220
  >
221
221
  <Field
@@ -240,7 +240,7 @@ exports[`renders the Questions 1`] = `
240
240
  "name": "name",
241
241
  "ref": <input
242
242
  aria-required="true"
243
- class="govgr-input"
243
+ class="ds-input"
244
244
  name="name"
245
245
  type="text"
246
246
  />,
@@ -357,24 +357,24 @@ exports[`renders the Questions 1`] = `
357
357
  error={false}
358
358
  >
359
359
  <ForwardRef(Grid)
360
- className="govgr-field"
360
+ className="ds-field"
361
361
  item={true}
362
362
  xs={12}
363
363
  >
364
364
  <ForwardRef(Base)
365
365
  as="div"
366
- className="govgr-field xs:govgr-grid__col-span-12"
366
+ className="ds-field xs:ds-grid__col-span-12"
367
367
  >
368
368
  <div
369
- className="govgr-field xs:govgr-grid__col-span-12"
369
+ className="ds-field xs:ds-grid__col-span-12"
370
370
  >
371
371
  <ForwardRef(LabelContainer)>
372
372
  <ForwardRef(Base)
373
373
  as="label"
374
- className="govgr-label"
374
+ className="ds-label"
375
375
  >
376
376
  <label
377
- className="govgr-label"
377
+ className="ds-label"
378
378
  >
379
379
  <Label
380
380
  label={
@@ -389,10 +389,10 @@ exports[`renders the Questions 1`] = `
389
389
  >
390
390
  <ForwardRef(Base)
391
391
  as="span"
392
- className="govgr-heading-sm"
392
+ className="ds-heading-sm"
393
393
  >
394
394
  <span
395
- className="govgr-heading-sm"
395
+ className="ds-heading-sm"
396
396
  >
397
397
  name.field.primary
398
398
  </span>
@@ -401,10 +401,10 @@ exports[`renders the Questions 1`] = `
401
401
  <ForwardRef(Hint)>
402
402
  <ForwardRef(Base)
403
403
  as="p"
404
- className="govgr-hint"
404
+ className="ds-hint"
405
405
  >
406
406
  <p
407
- className="govgr-hint"
407
+ className="ds-hint"
408
408
  >
409
409
  name.field.secondary
410
410
  </p>
@@ -424,7 +424,7 @@ exports[`renders the Questions 1`] = `
424
424
  "name": "name",
425
425
  "ref": <input
426
426
  aria-required="true"
427
- class="govgr-input"
427
+ class="ds-input"
428
428
  name="name"
429
429
  type="text"
430
430
  />,
@@ -536,7 +536,7 @@ exports[`renders the Questions 1`] = `
536
536
  <ForwardRef(Base)
537
537
  aria-required={true}
538
538
  as="input"
539
- className="govgr-input"
539
+ className="ds-input"
540
540
  disabled={false}
541
541
  name="name"
542
542
  onBlur={[Function]}
@@ -545,7 +545,7 @@ exports[`renders the Questions 1`] = `
545
545
  >
546
546
  <input
547
547
  aria-required={true}
548
- className="govgr-input"
548
+ className="ds-input"
549
549
  disabled={false}
550
550
  name="name"
551
551
  onBlur={[Function]}
@@ -570,12 +570,12 @@ exports[`renders the Questions 1`] = `
570
570
  >
571
571
  <ForwardRef(Base)
572
572
  as="button"
573
- className="govgr-btn-primary govgr-btn"
573
+ className="ds-btn-primary ds-btn"
574
574
  printHidden={true}
575
575
  type="submit"
576
576
  >
577
577
  <button
578
- className="govgr-btn-primary govgr-btn govgr-print-hidden"
578
+ className="ds-btn-primary ds-btn ds-print-hidden"
579
579
  type="submit"
580
580
  >
581
581
  Συνέχεια
@@ -20,7 +20,7 @@ export interface Limit {
20
20
  }
21
21
 
22
22
  export const Image: React.FC<ImageProps> = React.memo(function Image({ src }) {
23
- return <img src={src} className="govgr-image--ratio" />;
23
+ return <img src={src} className="ds-image--ratio" />;
24
24
  });
25
25
  export interface ImageInputProps extends Omit<UncontrolledFieldProps, 'extra'> {
26
26
  extra?: {
@@ -76,7 +76,7 @@ export const ImageInput: React.FC<ImageInputProps> = React.forwardRef(
76
76
  </Paragraph>
77
77
  </>
78
78
  ) : (
79
- <CoreHint className="govgr-dashed--border">
79
+ <CoreHint className="ds-dashed--border">
80
80
  {t('upload.no_image')}
81
81
  </CoreHint>
82
82
  )}
@@ -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
  />
package/src/lazy.js ADDED
@@ -0,0 +1,60 @@
1
+ import {lazy} from 'react';
2
+ export default {
3
+ 'FieldBase': lazy(() => import('@digigov/form/Field/FieldBase').then((module)=> ({default: module['FieldBase']}))),
4
+ 'FieldBaseContainer': lazy(() => import('@digigov/form/Field/FieldBaseContainer').then((module)=> ({default: module['FieldBaseContainer']}))),
5
+ 'FieldConditional': lazy(() => import('@digigov/form/Field/FieldConditional').then((module)=> ({default: module['FieldConditional']}))),
6
+ 'Field': lazy(() => import('@digigov/form/internal').then((module)=> ({default: module['Field']}))),
7
+ 'FieldArray': lazy(() => import('@digigov/form/FieldArray').then((module)=> ({default: module['FieldArray']}))),
8
+ 'FieldObject': lazy(() => import('@digigov/form/FieldObject').then((module)=> ({default: module['FieldObject']}))),
9
+ 'FieldsetWithContext': lazy(() => import('@digigov/form/Fieldset/FieldsetWithContext').then((module)=> ({default: module['FieldsetWithContext']}))),
10
+ 'Fieldset': lazy(() => import('@digigov/form/Fieldset').then((module)=> ({default: module['Fieldset']}))),
11
+ 'FieldsetBody': lazy(() => import('@digigov/form/Fieldset').then((module)=> ({default: module['FieldsetBody']}))),
12
+ 'FieldsetCaption': lazy(() => import('@digigov/form/Fieldset').then((module)=> ({default: module['FieldsetCaption']}))),
13
+ 'FieldsetLabel': lazy(() => import('@digigov/form/Fieldset').then((module)=> ({default: module['FieldsetLabel']}))),
14
+ 'FormBase': lazy(() => import('@digigov/form/FormBuilder/FormBuilder').then((module)=> ({default: module['FormBase']}))),
15
+ 'FormBuilder': lazy(() => import('@digigov/form/FormBuilder/FormBuilder').then((module)=> ({default: module['FormBuilder']}))),
16
+ 'FormContext': lazy(() => import('@digigov/form/FormContext').then((module)=> ({default: module['FormContext']}))),
17
+ 'Checkboxes': lazy(() => import('@digigov/form/inputs/Checkboxes').then((module)=> ({default: module['Checkboxes']}))),
18
+ 'DateInput': lazy(() => import('@digigov/form/inputs/DateInput').then((module)=> ({default: module['DateInput']}))),
19
+ 'FileInput': lazy(() => import('@digigov/form/inputs/FileInput').then((module)=> ({default: module['FileInput']}))),
20
+ 'Input': lazy(() => import('@digigov/form/inputs/Input').then((module)=> ({default: module['Input']}))),
21
+ 'Label': lazy(() => import('@digigov/form/inputs/Label').then((module)=> ({default: module['Label']}))),
22
+ 'Questions': lazy(() => import('@digigov/form/Questions/Questions').then((module)=> ({default: module['Questions']}))),
23
+ 'Radio': lazy(() => import('@digigov/form/internal').then((module)=> ({default: module['Radio']}))),
24
+ 'Select': lazy(() => import('@digigov/form/inputs/Select').then((module)=> ({default: module['Select']}))),
25
+ 'Step': lazy(() => import('@digigov/form/Questions/Step/Step').then((module)=> ({default: module['Step']}))),
26
+ 'ReviewStep': lazy(() => import('@digigov/form/Questions/Step/ReviewStep').then((module)=> ({default: module['ReviewStep']}))),
27
+ 'StepArrayReview': lazy(() => import('@digigov/form/Questions/Step/StepArrayReview').then((module)=> ({default: module['StepArrayReview']}))),
28
+ 'StepContext': lazy(() => import('@digigov/form/Questions/Step/StepContext').then((module)=> ({default: module['StepContext']}))),
29
+ 'StepDescription': lazy(() => import('@digigov/form/Questions/Step/StepDescription').then((module)=> ({default: module['StepDescription']}))),
30
+ 'StepDescriptionBase': lazy(() => import('@digigov/form/Questions/Step/StepDescription').then((module)=> ({default: module['StepDescriptionBase']}))),
31
+ 'StepForm': lazy(() => import('@digigov/form/Questions/Step/StepForm').then((module)=> ({default: module['StepForm']}))),
32
+ 'StepQuote': lazy(() => import('@digigov/form/Questions/Step/StepQuote').then((module)=> ({default: module['StepQuote']}))),
33
+ 'StepTitle': lazy(() => import('@digigov/form/Questions/Step/StepTitle').then((module)=> ({default: module['StepTitle']}))),
34
+ 'StepTitleBase': lazy(() => import('@digigov/form/Questions/Step/StepTitle').then((module)=> ({default: module['StepTitleBase']}))),
35
+ 'StepTitleHeading': lazy(() => import('@digigov/form/Questions/Step/StepTitle').then((module)=> ({default: module['StepTitleHeading']}))),
36
+ 'RadioButtonsGroup': lazy(() => import('@digigov/form/inputs/Radio').then((module)=> ({default: module['RadioButtonsGroup']}))),
37
+ 'ImageInput': lazy(() => import('@digigov/form/inputs/ImageInput').then((module)=> ({default: module['ImageInput']}))),
38
+ 'OtpInput': lazy(() => import('@digigov/form/inputs/OtpInput').then((module)=> ({default: module['OtpInput']}))),
39
+ 'AutoCompleteInput': lazy(() => import('@digigov/form/inputs/AutoCompleteInput').then((module)=> ({default: module['AutoCompleteInput']}))),
40
+ 'Image': lazy(() => import('@digigov/form/inputs/ImageInput').then((module)=> ({default: module['Image']}))),
41
+ 'REMOVE_SPACES': lazy(() => import('@digigov/form/inputs/OtpInput').then((module)=> ({default: module['REMOVE_SPACES']}))),
42
+ 'RE_DIGIT': lazy(() => import('@digigov/form/inputs/OtpInput').then((module)=> ({default: module['RE_DIGIT']}))),
43
+ 'AddObjects': lazy(() => import('@digigov/form/MultiplicityField/add-objects').then((module)=> ({default: module['AddObjects']}))),
44
+ 'ListObject': lazy(() => import('@digigov/form/MultiplicityField').then((module)=> ({default: module['ListObject']}))),
45
+ 'Multiplicity': lazy(() => import('@digigov/form/MultiplicityField').then((module)=> ({default: module['Multiplicity']}))),
46
+ 'QuestionsContext': lazy(() => import('@digigov/form/Questions/QuestionsContext').then((module)=> ({default: module['QuestionsContext']}))),
47
+ 'AFM_VALIDATOR': lazy(() => import('@digigov/form/validators/utils/afm').then((module)=> ({default: module['AFM_VALIDATOR']}))),
48
+ 'FILE_MAX_SIZE_VALIDATOR': lazy(() => import('@digigov/form/validators/utils/file').then((module)=> ({default: module['FILE_MAX_SIZE_VALIDATOR']}))),
49
+ 'IBAN_VALIDATOR': lazy(() => import('@digigov/form/validators/utils/iban').then((module)=> ({default: module['IBAN_VALIDATOR']}))),
50
+ 'IMAGE_DIMENSION_VALIDATOR': lazy(() => import('@digigov/form/validators/utils/image').then((module)=> ({default: module['IMAGE_DIMENSION_VALIDATOR']}))),
51
+ 'OTP_VALIDATOR': lazy(() => import('@digigov/form/validators/utils/otp').then((module)=> ({default: module['OTP_VALIDATOR']}))),
52
+ 'MOBILE_PHONE_VALIDATOR': lazy(() => import('@digigov/form/validators/utils/phone').then((module)=> ({default: module['MOBILE_PHONE_VALIDATOR']}))),
53
+ 'PHONE_NUMBER_VALIDATOR': lazy(() => import('@digigov/form/validators/utils/phone').then((module)=> ({default: module['PHONE_NUMBER_VALIDATOR']}))),
54
+ 'POSTALCODE_VALIDATOR': lazy(() => import('@digigov/form/validators/utils/postal_code').then((module)=> ({default: module['POSTALCODE_VALIDATOR']}))),
55
+ 'UUID4_VALIDATOR': lazy(() => import('@digigov/form/validators/utils/uuid4').then((module)=> ({default: module['UUID4_VALIDATOR']}))),
56
+ 'TEXT_LIMIT_VALIDATOR': lazy(() => import('@digigov/form/validators/utils/text_limit').then((module)=> ({default: module['TEXT_LIMIT_VALIDATOR']}))),
57
+ 'INT_VALIDATOR': lazy(() => import('@digigov/form/validators/utils/int').then((module)=> ({default: module['INT_VALIDATOR']}))),
58
+ 'NUMBER_VALIDATOR': lazy(() => import('@digigov/form/validators/utils/number').then((module)=> ({default: module['NUMBER_VALIDATOR']}))),
59
+
60
+ }
@@ -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
  };