@tepez/joi-phone-number-extensions 0.0.0 → 1.2.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.
@@ -1,123 +1,123 @@
1
- # joi-phone-number-extensions
2
- > A joi extension for validating and formatting phone numbers using google-libphonenumber
3
-
4
- [![npm version](https://badge.fury.io/js/%40tepez%2Fjoi-phone-number-extensions.svg)](https://badge.fury.io/js/%40tepez%2Fjoi-phone-number-extensions)
5
- [![Build Status](https://secure.travis-ci.org/tepez/joi-phone-number-extensions.svg?branch=master)](http://travis-ci.org/tepez/joi-phone-number-extensions)
6
-
7
- ## Install
8
-
9
- ```
10
- npm install --save @tepez/joi-phone-number-extensions
11
- ```
12
-
13
- ## Usage
14
-
15
- ```
16
- const BaseJoi = require('joi');
17
- const JoiPhoneNumberExtensions = require('joi-phone-number-extensions');
18
- const Joi = BaseJoi.extend(JoiPhoneNumberExtensions);
19
-
20
- const schema = Joi.phoneNumber().defaultRegion('US').type('MOBILE').format('E164');
21
- schema.validate('+1 541-754-3010', (err, value) => {
22
- console.log(value) // +15417543010
23
- });
24
- ```
25
-
26
- ## API
27
-
28
- ### `phoneNumber` - inherits from `string`
29
-
30
- Generates a schema object that matches phone numbers.
31
-
32
- #### `phoneNumber.defaultRegion(regionCode)`
33
-
34
- Use this region code as default if given a non-international number.
35
-
36
- `regionCode` is one of the code supported by [libphonenumber](https://github.com/ruimarinho/google-libphonenumber), e.g. UG, US, UY or UZ.
37
-
38
- ```js
39
- const withDefaultRegion = Joi.phoneNumber().defaultRegion('US');
40
- const withoutDefaultRegion = Joi.phoneNumber();
41
-
42
- // valid
43
- withDefaultRegion.validate('(541) 754-3010');
44
-
45
- withDefaultRegion.validate('+1 541-754-3010');
46
- withoutDefaultRegion.validate('+1 541-754-3010');
47
-
48
- // invalid
49
- withoutDefaultRegion.validate('(541) 754-3010');
50
- ```
51
-
52
- #### `phoneNumber.region(regionCode)`
53
-
54
- Require the number to be a valid number in given region.
55
-
56
- `regionCode` is one of the code supported by [libphonenumber](https://github.com/ruimarinho/google-libphonenumber), e.g. UG, US, UY or UZ.
57
-
58
- ```js
59
- const schema = Joi.phoneNumber().region('FR');
60
-
61
- // valid
62
- schema.validate('+33752961860');
63
-
64
- // invalid
65
- schema.validate('+1 541-754-3010');
66
- ```
67
-
68
- `regionCode` can also be a `ref` for another property:
69
-
70
- ```js
71
- const schema = Joi.object().keys({
72
- phone: Joi.phoneNumber().region(Joi.ref('region')),
73
- region: Joi.string()
74
- });
75
- // valid
76
- schema.validate({
77
- phone: '+33752961860',
78
- region: 'FR'
79
- });
80
- ```
81
-
82
- #### `phoneNumber.type(type)`
83
-
84
- Require the number to a valid number of given type.
85
-
86
- `type` must be one of the types supported by [libphonenumber](https://github.com/ruimarinho/google-libphonenumber), e.g. FIXED_LINE, MOBILE, FIXED_LINE_OR_MOBILE, TOLL_FREE, PREMIUM_RATE, SHARED_COST, VOIP, PERSONAL_NUMBER, PAGER, UAN, VOICEMAIL or UNKNOWN.
87
-
88
- ```js
89
- const schema = Joi.phoneNumber().type('FIXED_LINE');
90
-
91
- // valid
92
- schema.validate('+1 541-754-3010');
93
-
94
- // invalid
95
- schema.validate('+972525555555');
96
- ```
97
-
98
- #### `phoneNumber.format(format)`
99
-
100
- Requires the number to be formatted in given format. If the validation `convert` option is on
101
- (enabled by default), will return the number as formatted in given format.
102
-
103
- `format` must be one of the types supported by [libphonenumber](https://github.com/ruimarinho/google-libphonenumber), e.g. E164, INTERNATIONAL, NATIONAL or RFC3966.
104
-
105
- ```js
106
- Joi.phoneNumber().format('NATIONAL').validate('+1-541-754-3010')
107
- // (541) 754-3010'
108
-
109
- Joi.phoneNumber().format('E164').validate('+1-541-754-3010')
110
- // +15417543010
111
- ```
112
-
113
- *See tests for more examples*
114
-
115
- ## TypeScript
116
-
117
- ```typescript
118
- import * as Joi from 'joi'
119
- import Extension, { JoiWithPhoneNumberExtension } from '@tepez/joi-phone-number-extensions'
120
-
121
- const ExtendedJoi: JoiWithPhoneNumberExtension = Joi.extend(Extension);
122
- // Type information for the phoneNumber() method is now available to ExtendedJoi
1
+ # joi-phone-number-extensions
2
+ > A joi extension for validating and formatting phone numbers using google-libphonenumber
3
+
4
+ [![npm version](https://badge.fury.io/js/%40tepez%2Fjoi-phone-number-extensions.svg)](https://badge.fury.io/js/%40tepez%2Fjoi-phone-number-extensions)
5
+ [![Build Status](https://secure.travis-ci.org/tepez/joi-phone-number-extensions.svg?branch=master)](http://travis-ci.org/tepez/joi-phone-number-extensions)
6
+
7
+ ## Install
8
+
9
+ ```
10
+ npm install --save @tepez/joi-phone-number-extensions
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```
16
+ const BaseJoi = require('joi');
17
+ const JoiPhoneNumberExtensions = require('joi-phone-number-extensions');
18
+ const Joi = BaseJoi.extend(JoiPhoneNumberExtensions);
19
+
20
+ const schema = Joi.phoneNumber().defaultRegion('US').type('MOBILE').format('E164');
21
+ schema.validate('+1 541-754-3010', (err, value) => {
22
+ console.log(value) // +15417543010
23
+ });
24
+ ```
25
+
26
+ ## API
27
+
28
+ ### `phoneNumber` - inherits from `string`
29
+
30
+ Generates a schema object that matches phone numbers.
31
+
32
+ #### `phoneNumber.defaultRegion(regionCode)`
33
+
34
+ Use this region code as default if given a non-international number.
35
+
36
+ `regionCode` is one of the code supported by [libphonenumber](https://github.com/ruimarinho/google-libphonenumber), e.g. UG, US, UY or UZ.
37
+
38
+ ```js
39
+ const withDefaultRegion = Joi.phoneNumber().defaultRegion('US');
40
+ const withoutDefaultRegion = Joi.phoneNumber();
41
+
42
+ // valid
43
+ withDefaultRegion.validate('(541) 754-3010');
44
+
45
+ withDefaultRegion.validate('+1 541-754-3010');
46
+ withoutDefaultRegion.validate('+1 541-754-3010');
47
+
48
+ // invalid
49
+ withoutDefaultRegion.validate('(541) 754-3010');
50
+ ```
51
+
52
+ #### `phoneNumber.region(regionCode)`
53
+
54
+ Require the number to be a valid number in given region.
55
+
56
+ `regionCode` is one of the code supported by [libphonenumber](https://github.com/ruimarinho/google-libphonenumber), e.g. UG, US, UY or UZ.
57
+
58
+ ```js
59
+ const schema = Joi.phoneNumber().region('FR');
60
+
61
+ // valid
62
+ schema.validate('+33752961860');
63
+
64
+ // invalid
65
+ schema.validate('+1 541-754-3010');
66
+ ```
67
+
68
+ `regionCode` can also be a `ref` for another property:
69
+
70
+ ```js
71
+ const schema = Joi.object().keys({
72
+ phone: Joi.phoneNumber().region(Joi.ref('region')),
73
+ region: Joi.string()
74
+ });
75
+ // valid
76
+ schema.validate({
77
+ phone: '+33752961860',
78
+ region: 'FR'
79
+ });
80
+ ```
81
+
82
+ #### `phoneNumber.type(type)`
83
+
84
+ Require the number to a valid number of given type.
85
+
86
+ `type` must be one of the types supported by [libphonenumber](https://github.com/ruimarinho/google-libphonenumber), e.g. FIXED_LINE, MOBILE, FIXED_LINE_OR_MOBILE, TOLL_FREE, PREMIUM_RATE, SHARED_COST, VOIP, PERSONAL_NUMBER, PAGER, UAN, VOICEMAIL or UNKNOWN.
87
+
88
+ ```js
89
+ const schema = Joi.phoneNumber().type('FIXED_LINE');
90
+
91
+ // valid
92
+ schema.validate('+1 541-754-3010');
93
+
94
+ // invalid
95
+ schema.validate('+972525555555');
96
+ ```
97
+
98
+ #### `phoneNumber.format(format)`
99
+
100
+ Requires the number to be formatted in given format. If the validation `convert` option is on
101
+ (enabled by default), will return the number as formatted in given format.
102
+
103
+ `format` must be one of the types supported by [libphonenumber](https://github.com/ruimarinho/google-libphonenumber), e.g. E164, INTERNATIONAL, NATIONAL or RFC3966.
104
+
105
+ ```js
106
+ Joi.phoneNumber().format('NATIONAL').validate('+1-541-754-3010')
107
+ // (541) 754-3010'
108
+
109
+ Joi.phoneNumber().format('E164').validate('+1-541-754-3010')
110
+ // +15417543010
111
+ ```
112
+
113
+ *See tests for more examples*
114
+
115
+ ## TypeScript
116
+
117
+ ```typescript
118
+ import * as Joi from 'joi'
119
+ import Extension, { JoiWithPhoneNumberExtension } from '@tepez/joi-phone-number-extensions'
120
+
121
+ const ExtendedJoi: JoiWithPhoneNumberExtension = Joi.extend(Extension);
122
+ // Type information for the phoneNumber() method is now available to ExtendedJoi
123
123
  ```
@@ -0,0 +1,12 @@
1
+ import { TypedExtension } from '@tepez/joi-misc-extensions';
2
+ import { PhoneNumberFormat as PNF, PhoneNumberType as PNT } from 'google-libphonenumber';
3
+ import * as Joi from 'joi';
4
+ import { Reference } from 'joi';
5
+ interface IFlags {
6
+ phoneNumberDefaultRegion?: string;
7
+ phoneNumberRegion?: string | Reference;
8
+ phoneNumberType?: keyof typeof PNT;
9
+ phoneNumberFormat?: keyof typeof PNF;
10
+ }
11
+ export declare const phoneNumExtensions: (joi: typeof Joi) => TypedExtension<IFlags>;
12
+ export {};
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.phoneNumExtensions = void 0;
4
+ const ts_utils_1 = require("@tepez/ts-utils");
5
+ const google_libphonenumber_1 = require("google-libphonenumber");
6
+ const en_1 = require("./i18n/en");
7
+ const utils_1 = require("./utils");
8
+ const he_1 = require("./i18n/he");
9
+ const Assert = require('@hapi/hoek/lib/assert');
10
+ const phoneNumberUtil = google_libphonenumber_1.PhoneNumberUtil.getInstance();
11
+ function typesMatch(type1, type2) {
12
+ return type1 === type2 ||
13
+ (type1 === google_libphonenumber_1.PhoneNumberType.FIXED_LINE_OR_MOBILE && (type2 === google_libphonenumber_1.PhoneNumberType.MOBILE || type2 === google_libphonenumber_1.PhoneNumberType.FIXED_LINE)) ||
14
+ (type2 === google_libphonenumber_1.PhoneNumberType.FIXED_LINE_OR_MOBILE && (type1 === google_libphonenumber_1.PhoneNumberType.MOBILE || type1 === google_libphonenumber_1.PhoneNumberType.FIXED_LINE));
15
+ }
16
+ const assertUpperCaseString = (name, value, validValues) => {
17
+ Assert(value, name, 'is required');
18
+ Assert(typeof value === 'string', name, 'must be a string');
19
+ const ret = value.toUpperCase();
20
+ Assert(validValues.includes(ret), name, 'must be one of', validValues.join(', '));
21
+ return ret;
22
+ };
23
+ exports.phoneNumExtensions = function (joi) {
24
+ const regionValidation = joi
25
+ .string()
26
+ .uppercase()
27
+ .valid(...utils_1.validRegions)
28
+ .required();
29
+ const pntKeys = Object.keys(google_libphonenumber_1.PhoneNumberType);
30
+ const pnfKeys = Object.keys(google_libphonenumber_1.PhoneNumberFormat);
31
+ return {
32
+ type: 'phoneNumber',
33
+ base: joi.string(),
34
+ messages: Object.assign(Object.assign({}, en_1.phoneNumberExtensionsEnMessages), { he: he_1.phoneNumberExtensionsHeMessages }),
35
+ // https://github.com/sideway/joi/blob/v17.4.2/lib/index.d.ts#L29
36
+ validate(value, helpers) {
37
+ if (!value) {
38
+ return {
39
+ value,
40
+ };
41
+ }
42
+ const phoneNumberRegion = helpers.schema.$_getFlag('phoneNumberRegion');
43
+ const phoneNumberDefaultRegion = helpers.schema.$_getFlag('phoneNumberDefaultRegion');
44
+ const phoneNumberType = helpers.schema.$_getFlag('phoneNumberType');
45
+ const phoneNumberFormat = helpers.schema.$_getFlag('phoneNumberFormat');
46
+ let regionSource = phoneNumberRegion
47
+ || phoneNumberDefaultRegion
48
+ || null;
49
+ let region;
50
+ if (joi.isRef(regionSource)) {
51
+ region = regionSource.resolve(value, helpers.state, helpers.prefs);
52
+ if (!region) {
53
+ return {
54
+ errors: helpers.error('phoneNumber.emptyFieldRef', { ref: regionSource.key }),
55
+ };
56
+ }
57
+ const regionValidationResult = regionValidation.validate(region);
58
+ if (regionValidationResult.error) {
59
+ return {
60
+ errors: helpers.error('phoneNumber.illegalRefRegion', { ref: regionSource.key }),
61
+ };
62
+ }
63
+ }
64
+ else {
65
+ region = regionSource;
66
+ }
67
+ let parsedNumber;
68
+ try {
69
+ parsedNumber = phoneNumberUtil.parse(value, region);
70
+ }
71
+ catch (err) {
72
+ return {
73
+ errors: helpers.error('phoneNumber.base', { value }),
74
+ };
75
+ }
76
+ if (phoneNumberRegion) {
77
+ if (!phoneNumberUtil.isValidNumberForRegion(parsedNumber, region)) {
78
+ return {
79
+ errors: helpers.error('phoneNumber.region', { value, region }),
80
+ };
81
+ }
82
+ }
83
+ else if (!phoneNumberUtil.isValidNumber(parsedNumber)) {
84
+ return {
85
+ errors: helpers.error('phoneNumber.base', { value }),
86
+ };
87
+ }
88
+ if (phoneNumberType) {
89
+ const numberType = phoneNumberUtil.getNumberType(parsedNumber);
90
+ if (!typesMatch(google_libphonenumber_1.PhoneNumberType[phoneNumberType], numberType)) {
91
+ const context = {
92
+ value,
93
+ type: phoneNumberType,
94
+ };
95
+ return {
96
+ errors: helpers.error('phoneNumber.type', context),
97
+ };
98
+ }
99
+ }
100
+ if (phoneNumberFormat) {
101
+ const formattedNumber = phoneNumberUtil.format(parsedNumber, google_libphonenumber_1.PhoneNumberFormat[phoneNumberFormat]);
102
+ if (helpers.prefs.convert) {
103
+ return {
104
+ value: formattedNumber,
105
+ };
106
+ }
107
+ else if (value !== formattedNumber) {
108
+ const context = {
109
+ value,
110
+ format: phoneNumberFormat,
111
+ };
112
+ return {
113
+ errors: helpers.error('phoneNumber.format', context),
114
+ };
115
+ }
116
+ }
117
+ return {
118
+ value: value,
119
+ };
120
+ },
121
+ rules: {
122
+ defaultRegion: ts_utils_1.assertT({
123
+ // region that we are expecting the number to be from
124
+ method(defaultRegion) {
125
+ return this.$_setFlag('phoneNumberDefaultRegion', assertUpperCaseString('defaultRegion', defaultRegion, utils_1.validRegions));
126
+ },
127
+ }),
128
+ region: ts_utils_1.assertT({
129
+ method(region) {
130
+ return this.$_setFlag('phoneNumberRegion', joi.isRef(region)
131
+ ? region
132
+ : assertUpperCaseString('region', region, utils_1.validRegions));
133
+ },
134
+ }),
135
+ numType: ts_utils_1.assertT({
136
+ method(type) {
137
+ return this.$_setFlag('phoneNumberType', assertUpperCaseString('type', type, pntKeys));
138
+ },
139
+ }),
140
+ format: ts_utils_1.assertT({
141
+ method(format) {
142
+ return this.$_setFlag('phoneNumberFormat', assertUpperCaseString('format', format, pnfKeys));
143
+ },
144
+ }),
145
+ },
146
+ };
147
+ };
148
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,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UUFDTixDQUFDO1FBQ0QsS0FBSyxFQUFFO1lBQ0gsYUFBYSxFQUFFLGtCQUFPLENBRVY7Z0JBQ1IscURBQXFEO2dCQUNyRCxNQUFNLENBQUMsYUFBcUI7b0JBQ3hCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FDakIsMEJBQTBCLEVBQzFCLHFCQUFxQixDQUFDLGVBQWUsRUFBRSxhQUFhLEVBQUUsb0JBQVksQ0FBQyxDQUN0RSxDQUFDO2dCQUNOLENBQUM7YUFDSixDQUFDO1lBQ0YsTUFBTSxFQUFFLGtCQUFPLENBRUg7Z0JBQ1IsTUFBTSxDQUFDLE1BQTBCO29CQUM3QixPQUFPLElBQUksQ0FBQyxTQUFTLENBQ2pCLG1CQUFtQixFQUNuQixHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQzt3QkFDYixDQUFDLENBQUMsTUFBTTt3QkFDUixDQUFDLENBQUMscUJBQXFCLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxvQkFBWSxDQUFDLENBQzlELENBQUM7Z0JBQ04sQ0FBQzthQUNKLENBQUM7WUFDRixPQUFPLEVBQUUsa0JBQU8sQ0FFSjtnQkFDUixNQUFNLENBQUMsSUFBc0I7b0JBQ3pCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FDakIsaUJBQWlCLEVBQ2pCLHFCQUFxQixDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFxQixDQUNuRSxDQUFDO2dCQUNOLENBQUM7YUFDSixDQUFDO1lBQ0YsTUFBTSxFQUFFLGtCQUFPLENBRUg7Z0JBQ1IsTUFBTSxDQUFDLE1BQXdCO29CQUMzQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQ2pCLG1CQUFtQixFQUNuQixxQkFBcUIsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBcUIsQ0FDdkUsQ0FBQztnQkFDTixDQUFDO2FBQ0osQ0FBQztTQUNMO0tBQ0osQ0FBQTtBQUNMLENBQUMsQ0FBQyIsImZpbGUiOiJleHRlbnNpb24uanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNeVJlZmVyZW5jZSwgVHlwZWRFeHRlbnNpb24sIFR5cGVkRXh0ZW5zaW9uUnVsZSB9IGZyb20gJ0B0ZXBlei9qb2ktbWlzYy1leHRlbnNpb25zJztcbmltcG9ydCB7IGFzc2VydFQgfSBmcm9tICdAdGVwZXovdHMtdXRpbHMnO1xuaW1wb3J0IHsgUGhvbmVOdW1iZXJGb3JtYXQgYXMgUE5GLCBQaG9uZU51bWJlclR5cGUgYXMgUE5ULCBQaG9uZU51bWJlclV0aWwgfSBmcm9tICdnb29nbGUtbGlicGhvbmVudW1iZXInXG5pbXBvcnQgKiBhcyBKb2kgZnJvbSAnam9pJ1xuaW1wb3J0IHsgUmVmZXJlbmNlIH0gZnJvbSAnam9pJ1xuaW1wb3J0IHsgcGhvbmVOdW1iZXJFeHRlbnNpb25zRW5NZXNzYWdlcyB9IGZyb20gJy4vaTE4bi9lbic7XG5pbXBvcnQgeyB2YWxpZFJlZ2lvbnMgfSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IHBob25lTnVtYmVyRXh0ZW5zaW9uc0hlTWVzc2FnZXMgfSBmcm9tICcuL2kxOG4vaGUnO1xuXG5jb25zdCBBc3NlcnQgPSByZXF1aXJlKCdAaGFwaS9ob2VrL2xpYi9hc3NlcnQnKTtcblxuXG5pbnRlcmZhY2UgSUZsYWdzIHtcbiAgICBwaG9uZU51bWJlckRlZmF1bHRSZWdpb24/OiBzdHJpbmdcbiAgICBwaG9uZU51bWJlclJlZ2lvbj86IHN0cmluZyB8IFJlZmVyZW5jZVxuICAgIHBob25lTnVtYmVyVHlwZT86IGtleW9mIHR5cGVvZiBQTlRcbiAgICBwaG9uZU51bWJlckZvcm1hdD86IGtleW9mIHR5cGVvZiBQTkZcbn1cblxuY29uc3QgcGhvbmVOdW1iZXJVdGlsID0gUGhvbmVOdW1iZXJVdGlsLmdldEluc3RhbmNlKCk7XG5cbmZ1bmN0aW9uIHR5cGVzTWF0Y2godHlwZTE6IFBOVCwgdHlwZTI6IFBOVCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0eXBlMSA9PT0gdHlwZTIgfHxcbiAgICAgICAgKHR5cGUxID09PSBQTlQuRklYRURfTElORV9PUl9NT0JJTEUgJiYgKHR5cGUyID09PSBQTlQuTU9CSUxFIHx8IHR5cGUyID09PSBQTlQuRklYRURfTElORSkpIHx8XG4gICAgICAgICh0eXBlMiA9PT0gUE5ULkZJWEVEX0xJTkVfT1JfTU9CSUxFICYmICh0eXBlMSA9PT0gUE5ULk1PQklMRSB8fCB0eXBlMSA9PT0gUE5ULkZJWEVEX0xJTkUpKTtcbn1cblxuY29uc3QgYXNzZXJ0VXBwZXJDYXNlU3RyaW5nID0gKG5hbWU6IHN0cmluZywgdmFsdWU6IGFueSwgdmFsaWRWYWx1ZXM6IHN0cmluZ1tdKTogc3RyaW5nID0+IHtcbiAgICBBc3NlcnQodmFsdWUsIG5hbWUsICdpcyByZXF1aXJlZCcpO1xuXG4gICAgQXNzZXJ0KHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycsIG5hbWUsICdtdXN0IGJlIGEgc3RyaW5nJyk7XG5cbiAgICBjb25zdCByZXQgPSB2YWx1ZS50b1VwcGVyQ2FzZSgpO1xuXG4gICAgQXNzZXJ0KHZhbGlkVmFsdWVzLmluY2x1ZGVzKHJldCksIG5hbWUsICdtdXN0IGJlIG9uZSBvZicsIHZhbGlkVmFsdWVzLmpvaW4oJywgJykpO1xuXG4gICAgcmV0dXJuIHJldCBhcyBzdHJpbmc7XG59XG5cbmV4cG9ydCBjb25zdCBwaG9uZU51bUV4dGVuc2lvbnMgPSBmdW5jdGlvbiAoam9pOiB0eXBlb2YgSm9pKTogVHlwZWRFeHRlbnNpb248SUZsYWdzPiB7XG4gICAgY29uc3QgcmVnaW9uVmFsaWRhdGlvbiA9IGpvaVxuICAgICAgICAuc3RyaW5nKClcbiAgICAgICAgLnVwcGVyY2FzZSgpXG4gICAgICAgIC52YWxpZCguLi52YWxpZFJlZ2lvbnMpXG4gICAgICAgIC5yZXF1aXJlZCgpO1xuXG4gICAgY29uc3QgcG50S2V5cyA9IE9iamVjdC5rZXlzKFBOVCk7XG4gICAgY29uc3QgcG5mS2V5cyA9IE9iamVjdC5rZXlzKFBORilcblxuICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdwaG9uZU51bWJlcicsXG4gICAgICAgIGJhc2U6IGpvaS5zdHJpbmcoKSxcbiAgICAgICAgbWVzc2FnZXM6IHtcbiAgICAgICAgICAgIC4uLnBob25lTnVtYmVyRXh0ZW5zaW9uc0VuTWVzc2FnZXMsXG4gICAgICAgICAgICBoZTogcGhvbmVOdW1iZXJFeHRlbnNpb25zSGVNZXNzYWdlcyxcbiAgICAgICAgfSBhcyBhbnksIC8vIGpvaSB0eXBlcyBkb2Vzbid0IHN1cHBvcnQgbGFuZ3VhZ2VzIGJ1dCBpdCdzIG9rIFxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vc2lkZXdheS9qb2kvYmxvYi92MTcuNC4yL2xpYi9pbmRleC5kLnRzI0wyOVxuICAgICAgICB2YWxpZGF0ZSh2YWx1ZSwgaGVscGVycykge1xuICAgICAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHBob25lTnVtYmVyUmVnaW9uID0gaGVscGVycy5zY2hlbWEuJF9nZXRGbGFnKCdwaG9uZU51bWJlclJlZ2lvbicpO1xuICAgICAgICAgICAgY29uc3QgcGhvbmVOdW1iZXJEZWZhdWx0UmVnaW9uID0gaGVscGVycy5zY2hlbWEuJF9nZXRGbGFnKCdwaG9uZU51bWJlckRlZmF1bHRSZWdpb24nKTtcbiAgICAgICAgICAgIGNvbnN0IHBob25lTnVtYmVyVHlwZSA9IGhlbHBlcnMuc2NoZW1hLiRfZ2V0RmxhZygncGhvbmVOdW1iZXJUeXBlJyk7XG4gICAgICAgICAgICBjb25zdCBwaG9uZU51bWJlckZvcm1hdCA9IGhlbHBlcnMuc2NoZW1hLiRfZ2V0RmxhZygncGhvbmVOdW1iZXJGb3JtYXQnKTtcblxuICAgICAgICAgICAgbGV0IHJlZ2lvblNvdXJjZTogc3RyaW5nIHwgUmVmZXJlbmNlID0gcGhvbmVOdW1iZXJSZWdpb25cbiAgICAgICAgICAgICAgICB8fCBwaG9uZU51bWJlckRlZmF1bHRSZWdpb25cbiAgICAgICAgICAgICAgICB8fCBudWxsO1xuXG4gICAgICAgICAgICBsZXQgcmVnaW9uOiBzdHJpbmc7XG5cbiAgICAgICAgICAgIGlmIChqb2kuaXNSZWYocmVnaW9uU291cmNlKSkge1xuICAgICAgICAgICAgICAgIHJlZ2lvbiA9IChyZWdpb25Tb3VyY2UgYXMgTXlSZWZlcmVuY2UpLnJlc29sdmUodmFsdWUsIGhlbHBlcnMuc3RhdGUsIGhlbHBlcnMucHJlZnMpO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFyZWdpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yczogaGVscGVycy5lcnJvcigncGhvbmVOdW1iZXIuZW1wdHlGaWVsZFJlZicsIHsgcmVmOiByZWdpb25Tb3VyY2Uua2V5IH0pLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHJlZ2lvblZhbGlkYXRpb25SZXN1bHQgPSByZWdpb25WYWxpZGF0aW9uLnZhbGlkYXRlKHJlZ2lvbik7XG4gICAgICAgICAgICAgICAgaWYgKHJlZ2lvblZhbGlkYXRpb25SZXN1bHQuZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yczogaGVscGVycy5lcnJvcigncGhvbmVOdW1iZXIuaWxsZWdhbFJlZlJlZ2lvbicsIHsgcmVmOiByZWdpb25Tb3VyY2Uua2V5IH0pLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVnaW9uID0gcmVnaW9uU291cmNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgcGFyc2VkTnVtYmVyO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHBhcnNlZE51bWJlciA9IHBob25lTnVtYmVyVXRpbC5wYXJzZSh2YWx1ZSwgcmVnaW9uKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yczogaGVscGVycy5lcnJvcigncGhvbmVOdW1iZXIuYmFzZScsIHsgdmFsdWUgfSksXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHBob25lTnVtYmVyUmVnaW9uKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFwaG9uZU51bWJlclV0aWwuaXNWYWxpZE51bWJlckZvclJlZ2lvbihwYXJzZWROdW1iZXIsIHJlZ2lvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yczogaGVscGVycy5lcnJvcigncGhvbmVOdW1iZXIucmVnaW9uJywgeyB2YWx1ZSwgcmVnaW9uIH0pLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXBob25lTnVtYmVyVXRpbC5pc1ZhbGlkTnVtYmVyKHBhcnNlZE51bWJlcikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcnM6IGhlbHBlcnMuZXJyb3IoJ3Bob25lTnVtYmVyLmJhc2UnLCB7IHZhbHVlIH0pLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChwaG9uZU51bWJlclR5cGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJUeXBlID0gcGhvbmVOdW1iZXJVdGlsLmdldE51bWJlclR5cGUocGFyc2VkTnVtYmVyKTtcbiAgICAgICAgICAgICAgICBpZiAoIXR5cGVzTWF0Y2goUE5UW3Bob25lTnVtYmVyVHlwZV0sIG51bWJlclR5cGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IHBob25lTnVtYmVyVHlwZSxcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yczogaGVscGVycy5lcnJvcigncGhvbmVOdW1iZXIudHlwZScsIGNvbnRleHQpLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHBob25lTnVtYmVyRm9ybWF0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkTnVtYmVyID0gcGhvbmVOdW1iZXJVdGlsLmZvcm1hdChwYXJzZWROdW1iZXIsIFBORltwaG9uZU51bWJlckZvcm1hdF0pO1xuICAgICAgICAgICAgICAgIGlmIChoZWxwZXJzLnByZWZzLmNvbnZlcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmb3JtYXR0ZWROdW1iZXIsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSAhPT0gZm9ybWF0dGVkTnVtYmVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdDogcGhvbmVOdW1iZXJGb3JtYXQsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnM6IGhlbHBlcnMuZXJyb3IoJ3Bob25lTnVtYmVyLmZvcm1hdCcsIGNvbnRleHQpLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgICBydWxlczoge1xuICAgICAgICAgICAgZGVmYXVsdFJlZ2lvbjogYXNzZXJ0VDxUeXBlZEV4dGVuc2lvblJ1bGU8e1xuICAgICAgICAgICAgICAgIGRlZmF1bHRSZWdpb246IHN0cmluZ1xuICAgICAgICAgICAgfSwgSUZsYWdzPj4oe1xuICAgICAgICAgICAgICAgIC8vIHJlZ2lvbiB0aGF0IHdlIGFyZSBleHBlY3RpbmcgdGhlIG51bWJlciB0byBiZSBmcm9tXG4gICAgICAgICAgICAgICAgbWV0aG9kKGRlZmF1bHRSZWdpb246IHN0cmluZykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy4kX3NldEZsYWcoXG4gICAgICAgICAgICAgICAgICAgICAgICAncGhvbmVOdW1iZXJEZWZhdWx0UmVnaW9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydFVwcGVyQ2FzZVN0cmluZygnZGVmYXVsdFJlZ2lvbicsIGRlZmF1bHRSZWdpb24sIHZhbGlkUmVnaW9ucyksXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgcmVnaW9uOiBhc3NlcnRUPFR5cGVkRXh0ZW5zaW9uUnVsZTx7XG4gICAgICAgICAgICAgICAgcmVnaW9uOiBzdHJpbmcgfCBSZWZlcmVuY2VcbiAgICAgICAgICAgIH0sIElGbGFncz4+KHtcbiAgICAgICAgICAgICAgICBtZXRob2QocmVnaW9uOiBzdHJpbmcgfCBSZWZlcmVuY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuJF9zZXRGbGFnKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3Bob25lTnVtYmVyUmVnaW9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGpvaS5pc1JlZihyZWdpb24pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyByZWdpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGFzc2VydFVwcGVyQ2FzZVN0cmluZygncmVnaW9uJywgcmVnaW9uLCB2YWxpZFJlZ2lvbnMpLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIG51bVR5cGU6IGFzc2VydFQ8VHlwZWRFeHRlbnNpb25SdWxlPHtcbiAgICAgICAgICAgICAgICB0eXBlOiBrZXlvZiB0eXBlb2YgUE5UXG4gICAgICAgICAgICB9LCBJRmxhZ3M+Pih7XG4gICAgICAgICAgICAgICAgbWV0aG9kKHR5cGU6IGtleW9mIHR5cGVvZiBQTlQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuJF9zZXRGbGFnKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3Bob25lTnVtYmVyVHlwZScsXG4gICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRVcHBlckNhc2VTdHJpbmcoJ3R5cGUnLCB0eXBlLCBwbnRLZXlzKSBhcyBrZXlvZiB0eXBlb2YgUE5ULFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGZvcm1hdDogYXNzZXJ0VDxUeXBlZEV4dGVuc2lvblJ1bGU8e1xuICAgICAgICAgICAgICAgIGZvcm1hdDoga2V5b2YgdHlwZW9mIFBORlxuICAgICAgICAgICAgfSwgSUZsYWdzPj4oe1xuICAgICAgICAgICAgICAgIG1ldGhvZChmb3JtYXQ6IGtleW9mIHR5cGVvZiBQTkYpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuJF9zZXRGbGFnKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3Bob25lTnVtYmVyRm9ybWF0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydFVwcGVyQ2FzZVN0cmluZygnZm9ybWF0JywgZm9ybWF0LCBwbmZLZXlzKSBhcyBrZXlvZiB0eXBlb2YgUE5GLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgfSxcbiAgICB9XG59O1xuXG4iXX0=
@@ -0,0 +1,8 @@
1
+ export declare const phoneNumberExtensionsEnMessages: {
2
+ 'phoneNumber.base': string;
3
+ 'phoneNumber.region': string;
4
+ 'phoneNumber.emptyFieldRef': string;
5
+ 'phoneNumber.illegalRefRegion': string;
6
+ 'phoneNumber.type': string;
7
+ 'phoneNumber.format': string;
8
+ };
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.phoneNumberExtensionsEnMessages = void 0;
4
+ const utils_1 = require("../utils");
5
+ exports.phoneNumberExtensionsEnMessages = {
6
+ 'phoneNumber.base': '{{#label}} must be a valid phone number',
7
+ 'phoneNumber.region': '{{#label}} must be number of region {{#region}}',
8
+ 'phoneNumber.emptyFieldRef': 'region reference "{{#ref}}" must point to a non empty field',
9
+ 'phoneNumber.illegalRefRegion': `region reference "{{#ref}}" must be one of [${utils_1.validRegions.join(', ')}]`,
10
+ 'phoneNumber.type': '{{#label}} must be a {{#type}} phone number',
11
+ 'phoneNumber.format': '{{#label}} must be formatted in {{#format}} format',
12
+ };
13
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pMThuL2VuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG9DQUF3QztBQUUzQixRQUFBLCtCQUErQixHQUFHO0lBQzNDLGtCQUFrQixFQUFFLHlDQUF5QztJQUM3RCxvQkFBb0IsRUFBRSxpREFBaUQ7SUFDdkUsMkJBQTJCLEVBQUUsNkRBQTZEO0lBQzFGLDhCQUE4QixFQUFFLCtDQUErQyxvQkFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRztJQUN6RyxrQkFBa0IsRUFBRSw2Q0FBNkM7SUFDakUsb0JBQW9CLEVBQUUsb0RBQW9EO0NBQzdFLENBQUMiLCJmaWxlIjoiaTE4bi9lbi5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHZhbGlkUmVnaW9ucyB9IGZyb20gJy4uL3V0aWxzJztcblxuZXhwb3J0IGNvbnN0IHBob25lTnVtYmVyRXh0ZW5zaW9uc0VuTWVzc2FnZXMgPSB7XG4gICAgJ3Bob25lTnVtYmVyLmJhc2UnOiAne3sjbGFiZWx9fSBtdXN0IGJlIGEgdmFsaWQgcGhvbmUgbnVtYmVyJyxcbiAgICAncGhvbmVOdW1iZXIucmVnaW9uJzogJ3t7I2xhYmVsfX0gbXVzdCBiZSBudW1iZXIgb2YgcmVnaW9uIHt7I3JlZ2lvbn19JyxcbiAgICAncGhvbmVOdW1iZXIuZW1wdHlGaWVsZFJlZic6ICdyZWdpb24gcmVmZXJlbmNlIFwie3sjcmVmfX1cIiBtdXN0IHBvaW50IHRvIGEgbm9uIGVtcHR5IGZpZWxkJyxcbiAgICAncGhvbmVOdW1iZXIuaWxsZWdhbFJlZlJlZ2lvbic6IGByZWdpb24gcmVmZXJlbmNlIFwie3sjcmVmfX1cIiBtdXN0IGJlIG9uZSBvZiBbJHt2YWxpZFJlZ2lvbnMuam9pbignLCAnKX1dYCxcbiAgICAncGhvbmVOdW1iZXIudHlwZSc6ICd7eyNsYWJlbH19IG11c3QgYmUgYSB7eyN0eXBlfX0gcGhvbmUgbnVtYmVyJyxcbiAgICAncGhvbmVOdW1iZXIuZm9ybWF0JzogJ3t7I2xhYmVsfX0gbXVzdCBiZSBmb3JtYXR0ZWQgaW4ge3sjZm9ybWF0fX0gZm9ybWF0Jyxcbn07Il19
@@ -0,0 +1,2 @@
1
+ import { phoneNumberExtensionsEnMessages } from './en';
2
+ export declare const phoneNumberExtensionsHeMessages: typeof phoneNumberExtensionsEnMessages;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.phoneNumberExtensionsHeMessages = void 0;
4
+ const utils_1 = require("../utils");
5
+ exports.phoneNumberExtensionsHeMessages = {
6
+ 'phoneNumber.base': '{{#label}} צריך להיות מספר טלפון תקין',
7
+ 'phoneNumber.region': '{{#label}} צריך להיות מספר טלפון תקין מ-{{#region}}',
8
+ 'phoneNumber.emptyFieldRef': 'ההפניה לאיזור "{{#ref}}" צריכה להוביל לשדה שאינו ריק',
9
+ 'phoneNumber.illegalRefRegion': `ההפנייה לאיזור "{{#ref}}" צריכה להוביל לאחד מ-[${utils_1.validRegions.join(', ')}]`,
10
+ 'phoneNumber.type': '{{#label}} צריך להיות מספר טלפון מסוג {{#type}}',
11
+ 'phoneNumber.format': '{{#label}} צריך להיות בפורמט של {{#format}}',
12
+ };
13
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pMThuL2hlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG9DQUF3QztBQUczQixRQUFBLCtCQUErQixHQUEyQztJQUNuRixrQkFBa0IsRUFBRSx1Q0FBdUM7SUFDM0Qsb0JBQW9CLEVBQUUscURBQXFEO0lBQzNFLDJCQUEyQixFQUFFLHNEQUFzRDtJQUNuRiw4QkFBOEIsRUFBRSxrREFBa0Qsb0JBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUc7SUFDNUcsa0JBQWtCLEVBQUUsaURBQWlEO0lBQ3JFLG9CQUFvQixFQUFFLDZDQUE2QztDQUN0RSxDQUFDIiwiZmlsZSI6ImkxOG4vaGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB2YWxpZFJlZ2lvbnMgfSBmcm9tICcuLi91dGlscyc7XG5pbXBvcnQgeyBwaG9uZU51bWJlckV4dGVuc2lvbnNFbk1lc3NhZ2VzIH0gZnJvbSAnLi9lbic7XG5cbmV4cG9ydCBjb25zdCBwaG9uZU51bWJlckV4dGVuc2lvbnNIZU1lc3NhZ2VzOiB0eXBlb2YgcGhvbmVOdW1iZXJFeHRlbnNpb25zRW5NZXNzYWdlcyA9IHtcbiAgICAncGhvbmVOdW1iZXIuYmFzZSc6ICd7eyNsYWJlbH19INem16jXmdeaINec15TXmdeV16og157Xodek16gg15jXnNek15XXnyDXqten15nXnycsXG4gICAgJ3Bob25lTnVtYmVyLnJlZ2lvbic6ICd7eyNsYWJlbH19INem16jXmdeaINec15TXmdeV16og157Xodek16gg15jXnNek15XXnyDXqten15nXnyDXni17eyNyZWdpb259fScsXG4gICAgJ3Bob25lTnVtYmVyLmVtcHR5RmllbGRSZWYnOiAn15TXlNek16DXmdeUINec15DXmdeW15XXqCBcInt7I3JlZn19XCIg16bXqNeZ15vXlCDXnNeU15XXkdeZ15wg15zXqdeT15Qg16nXkNeZ16DXlSDXqNeZ16cnLFxuICAgICdwaG9uZU51bWJlci5pbGxlZ2FsUmVmUmVnaW9uJzogYNeU15TXpNeg15nXmdeUINec15DXmdeW15XXqCBcInt7I3JlZn19XCIg16bXqNeZ15vXlCDXnNeU15XXkdeZ15wg15zXkNeX15Mg154tWyR7dmFsaWRSZWdpb25zLmpvaW4oJywgJyl9XWAsXG4gICAgJ3Bob25lTnVtYmVyLnR5cGUnOiAne3sjbGFiZWx9fSDXpteo15nXmiDXnNeU15nXldeqINee16HXpNeoINeY15zXpNeV158g157XodeV15Ige3sjdHlwZX19JyxcbiAgICAncGhvbmVOdW1iZXIuZm9ybWF0JzogJ3t7I2xhYmVsfX0g16bXqNeZ15og15zXlNeZ15XXqiDXkdek15XXqNee15gg16nXnCB7eyNmb3JtYXR9fScsXG59O1xuIl19
@@ -0,0 +1,4 @@
1
+ import { phoneNumExtensions } from './extension';
2
+ export * from './types';
3
+ export * from './extension';
4
+ export default phoneNumExtensions;
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ const extension_1 = require("./extension");
14
+ __exportStar(require("./types"), exports);
15
+ __exportStar(require("./extension"), exports);
16
+ exports.default = extension_1.phoneNumExtensions;
17
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBZ0Q7QUFFaEQsMENBQXVCO0FBQ3ZCLDhDQUEyQjtBQUUzQixrQkFBZSw4QkFBa0IsQ0FBQyIsImZpbGUiOiJpbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHBob25lTnVtRXh0ZW5zaW9ucyB9IGZyb20gJy4vZXh0ZW5zaW9uJ1xuXG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJ1xuZXhwb3J0ICogZnJvbSAnLi9leHRlbnNpb24nXG5cbmV4cG9ydCBkZWZhdWx0IHBob25lTnVtRXh0ZW5zaW9uczsiXX0=
@@ -0,0 +1,12 @@
1
+ import { PhoneNumberFormat as PNF, PhoneNumberType as PNT } from 'google-libphonenumber';
2
+ import * as Joi from 'joi';
3
+ import { Reference, StringSchema } from 'joi';
4
+ export interface PhoneNumberSchema extends StringSchema {
5
+ defaultRegion(region: string): this;
6
+ region(region: string | Reference): this;
7
+ numType(type: keyof typeof PNT | string): this;
8
+ format(format: keyof typeof PNF | string): this;
9
+ }
10
+ export declare type JoiWithPhoneNumberExtension = typeof Joi & {
11
+ phoneNumber(): PhoneNumberSchema;
12
+ };
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwiZmlsZSI6InR5cGVzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGhvbmVOdW1iZXJGb3JtYXQgYXMgUE5GLCBQaG9uZU51bWJlclR5cGUgYXMgUE5UIH0gZnJvbSAnZ29vZ2xlLWxpYnBob25lbnVtYmVyJ1xuaW1wb3J0ICogYXMgSm9pIGZyb20gJ2pvaSdcbmltcG9ydCB7IFJlZmVyZW5jZSwgU3RyaW5nU2NoZW1hIH0gZnJvbSAnam9pJ1xuXG5cbmV4cG9ydCBpbnRlcmZhY2UgUGhvbmVOdW1iZXJTY2hlbWEgZXh0ZW5kcyBTdHJpbmdTY2hlbWEge1xuICAgIGRlZmF1bHRSZWdpb24ocmVnaW9uOiBzdHJpbmcpOiB0aGlzXG5cbiAgICByZWdpb24ocmVnaW9uOiBzdHJpbmcgfCBSZWZlcmVuY2UpOiB0aGlzXG5cbiAgICBudW1UeXBlKHR5cGU6IGtleW9mIHR5cGVvZiBQTlQgfCBzdHJpbmcpOiB0aGlzXG5cbiAgICBmb3JtYXQoZm9ybWF0OiBrZXlvZiB0eXBlb2YgUE5GIHwgc3RyaW5nKTogdGhpc1xufVxuXG5leHBvcnQgdHlwZSBKb2lXaXRoUGhvbmVOdW1iZXJFeHRlbnNpb24gPSB0eXBlb2YgSm9pICYge1xuICAgIHBob25lTnVtYmVyKCk6IFBob25lTnVtYmVyU2NoZW1hXG59Il19
@@ -0,0 +1 @@
1
+ export declare const validRegions: string[];
package/dist/utils.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validRegions = void 0;
4
+ const PhoneNumber = require("google-libphonenumber");
5
+ exports.validRegions = Object.keys(
6
+ // as any because metadata is not in @types/google-libphonenumber
7
+ PhoneNumber.metadata.countryToMetadata);
8
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxREFBcUQ7QUFHeEMsUUFBQSxZQUFZLEdBQWEsTUFBTSxDQUFDLElBQUk7QUFDN0MsaUVBQWlFO0FBQ2hFLFdBQW1CLENBQUMsUUFBUSxDQUFDLGlCQUFpQixDQUNsRCxDQUFDIiwiZmlsZSI6InV0aWxzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgUGhvbmVOdW1iZXIgZnJvbSAnZ29vZ2xlLWxpYnBob25lbnVtYmVyJztcblxuXG5leHBvcnQgY29uc3QgdmFsaWRSZWdpb25zOiBzdHJpbmdbXSA9IE9iamVjdC5rZXlzKFxuICAgIC8vIGFzIGFueSBiZWNhdXNlIG1ldGFkYXRhIGlzIG5vdCBpbiBAdHlwZXMvZ29vZ2xlLWxpYnBob25lbnVtYmVyXG4gICAgKFBob25lTnVtYmVyIGFzIGFueSkubWV0YWRhdGEuY291bnRyeVRvTWV0YWRhdGEsXG4pOyJdfQ==
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@tepez/joi-phone-number-extensions",
3
- "version": "0.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "A joi extension for validating and formatting phone numbers using google-libphonenumber",
5
5
  "scripts": {
6
- "update": "node node_modules/gulp/bin/gulp.js build && node node_modules/np/cli.js --no-publish --no-yarn",
7
- "build": "node node_modules/gulp/bin/gulp.js build",
8
- "test": "node node_modules/gulp/bin/gulp.js build-unit-test"
6
+ "update": "npx gulp build && npx np --no-publish --no-yarn",
7
+ "build": "npx gulp build",
8
+ "dev": "yarn gulp --color dev-unit-test",
9
+ "dev-debug": "npx --node-options=--inspect-brk gulp dev-unit-test",
10
+ "test": "npx gulp build-unit-test",
11
+ "test-debug": "npx --node-options=--inspect-brk gulp build-unit-test"
9
12
  },
10
13
  "repository": {
11
14
  "type": "git",
@@ -20,16 +23,21 @@
20
23
  "types": "dist/index.d.ts",
21
24
  "main": "dist/index.js",
22
25
  "devDependencies": {
23
- "@tepez/joi-jasmine-helpers": "^0.1.0",
24
- "@tepez/typescript-build-gulp-tasks": "^3.1.0",
25
- "@types/jasmine": "^3.3.0",
26
- "gulp": "^3.9.1",
27
- "np": "^3.0.4"
26
+ "@tepez/joi-jasmine-helpers": "^1.0.0",
27
+ "@tepez/typescript-build-gulp-tasks": "^6.5.1",
28
+ "@tepez/typescript-common": "^0.2.2",
29
+ "@types/gulp": "^4.0.9",
30
+ "@types/jasmine": "^3.9.1",
31
+ "gulp": "^4.0.2",
32
+ "np": "^7.5.0"
28
33
  },
29
34
  "dependencies": {
30
- "@types/google-libphonenumber": "^7.4.17",
31
- "@types/joi": "^14.0.0",
32
- "@types/node": "^8.10.38",
33
- "google-libphonenumber": "^3.1.15"
35
+ "@hapi/hoek": "^9.0.0",
36
+ "@tepez/joi-misc-extensions": "^1.0.0",
37
+ "@tepez/ts-utils": "^0.1.1",
38
+ "@types/google-libphonenumber": "^7.4.21",
39
+ "@types/node": "*",
40
+ "google-libphonenumber": "^3.2.24",
41
+ "joi": "^17.4.2"
34
42
  }
35
43
  }