fix(lion-input-tel): upgrade to awesome-phonenumber v4
This commit is contained in:
parent
9ddde34c5b
commit
9b4cbb1dfc
10 changed files with 2450 additions and 3170 deletions
5
.changeset/cuddly-lizards-invite.md
Normal file
5
.changeset/cuddly-lizards-invite.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@lion/ui': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
[lion-input-tel] upgrade to awesome-phonenumber v4
|
||||||
5524
package-lock.json
generated
5524
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -72,10 +72,12 @@ export class LionInputTel extends LocalizeMixin(LionInput) {
|
||||||
get activePhoneNumberType() {
|
get activePhoneNumberType() {
|
||||||
let pn;
|
let pn;
|
||||||
try {
|
try {
|
||||||
pn = this._phoneUtil && this._phoneUtil(this.modelValue, this.activeRegion);
|
pn =
|
||||||
|
this._phoneUtil &&
|
||||||
|
this._phoneUtil.parsePhoneNumber(this.modelValue, { regionCode: this.activeRegion });
|
||||||
// eslint-disable-next-line no-empty
|
// eslint-disable-next-line no-empty
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
return pn?.g?.type || 'unknown';
|
return pn?.type || 'unknown';
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ts-ignore read only
|
// @ts-ignore read only
|
||||||
|
|
@ -325,7 +327,8 @@ export class LionInputTel extends LocalizeMixin(LionInput) {
|
||||||
const value = !(this.modelValue instanceof Unparseable)
|
const value = !(this.modelValue instanceof Unparseable)
|
||||||
? this.modelValue
|
? this.modelValue
|
||||||
: this.value.match(regex)?.join('');
|
: this.value.match(regex)?.join('');
|
||||||
const regionDerivedFromValue = value && this._phoneUtil && this._phoneUtil(value).g?.regionCode;
|
const regionDerivedFromValue =
|
||||||
|
value && this._phoneUtil && this._phoneUtil.parsePhoneNumber(value).regionCode;
|
||||||
|
|
||||||
if (regionDerivedFromValue && this._allowedOrAllRegions.includes(regionDerivedFromValue)) {
|
if (regionDerivedFromValue && this._allowedOrAllRegions.includes(regionDerivedFromValue)) {
|
||||||
this._setActiveRegion(regionDerivedFromValue);
|
this._setActiveRegion(regionDerivedFromValue);
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,25 @@
|
||||||
let resolveLoaded;
|
let resolveLoaded;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* - Handles lazy loading of the (relatively large) google-libphonenumber library, allowing
|
* @typedef {* & import('awesome-phonenumber')} AwesomePhoneNumber
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* - Handles lazy loading of the awesome-phonenumber library (relatively large, but way lighter than google-libphonenumber), allowing
|
||||||
* for quick first paints
|
* for quick first paints
|
||||||
* - Maintains one instance of phoneNumberUtil that can be shared across multiple places
|
* - Maintains one instance of phoneNumberUtil that can be shared across multiple places
|
||||||
* - Allows for easy mocking in unit tests
|
* - Allows for easy mocking in unit tests
|
||||||
*/
|
*/
|
||||||
export class PhoneUtilManager {
|
export class PhoneUtilManager {
|
||||||
static async loadLibPhoneNumber() {
|
static async loadLibPhoneNumber() {
|
||||||
const PhoneUtil = (await import('awesome-phonenumber')).default;
|
const PhoneUtil = /** @type {AwesomePhoneNumber} */ (await import('awesome-phonenumber'));
|
||||||
this.PhoneUtil = PhoneUtil;
|
this.PhoneUtil = { ...PhoneUtil };
|
||||||
resolveLoaded(undefined);
|
resolveLoaded(undefined);
|
||||||
return PhoneUtil;
|
return PhoneUtil;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if google-libphonenumber has been loaded
|
* Check if awesome-phonenumber has been loaded
|
||||||
*/
|
*/
|
||||||
static get isLoaded() {
|
static get isLoaded() {
|
||||||
return Boolean(this.PhoneUtil);
|
return Boolean(this.PhoneUtil);
|
||||||
|
|
@ -24,7 +28,7 @@ export class PhoneUtilManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait till google-libphonenumber has been loaded
|
* Wait till awesome-phonenumber has been loaded
|
||||||
* @example
|
* @example
|
||||||
* ```js
|
* ```js
|
||||||
* await PhoneUtilManager.loadComplete;
|
* await PhoneUtilManager.loadComplete;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import { PhoneUtilManager } from './PhoneUtilManager.js';
|
||||||
/**
|
/**
|
||||||
* @typedef {import('awesome-phonenumber').PhoneNumberFormat} PhoneNumberFormat
|
* @typedef {import('awesome-phonenumber').PhoneNumberFormat} PhoneNumberFormat
|
||||||
* @typedef {import('../types/index.js').RegionCode} RegionCode
|
* @typedef {import('../types/index.js').RegionCode} RegionCode
|
||||||
* @typedef {* & import('awesome-phonenumber').default} AwesomePhoneNumber
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -42,33 +41,32 @@ export function formatPhoneNumber(
|
||||||
return modelValue;
|
return modelValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line prefer-destructuring
|
const AwesomePhoneNumber = PhoneUtilManager.PhoneUtil;
|
||||||
const PhoneUtil = /** @type {AwesomePhoneNumber} */ (PhoneUtilManager.PhoneUtil);
|
|
||||||
|
|
||||||
let pn;
|
let pn;
|
||||||
try {
|
try {
|
||||||
pn = new PhoneUtil(modelValue, regionCode);
|
pn = AwesomePhoneNumber.parsePhoneNumber(modelValue, { regionCode });
|
||||||
// eslint-disable-next-line no-empty
|
// eslint-disable-next-line no-empty
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|
||||||
if (modelValue?.length >= 4 && modelValue?.length <= 16 && pn?.isValid()) {
|
if (modelValue?.length >= 4 && modelValue?.length <= 16 && pn?.valid) {
|
||||||
let formattedValue;
|
let formattedValue;
|
||||||
|
|
||||||
switch (formatStrategy) {
|
switch (formatStrategy) {
|
||||||
case 'e164':
|
case 'e164':
|
||||||
formattedValue = pn.getNumber('e164'); // -> '+46707123456' (default)
|
formattedValue = pn.number.e164; // -> '+46707123456' (default)
|
||||||
break;
|
break;
|
||||||
case 'international':
|
case 'international':
|
||||||
formattedValue = pn.getNumber('international'); // -> '+46 70 712 34 56'
|
formattedValue = pn.number.international; // -> '+46 70 712 34 56'
|
||||||
break;
|
break;
|
||||||
case 'national':
|
case 'national':
|
||||||
formattedValue = pn.getNumber('national'); // -> '070-712 34 56'
|
formattedValue = pn.number.national; // -> '070-712 34 56'
|
||||||
break;
|
break;
|
||||||
case 'rfc3966':
|
case 'rfc3966':
|
||||||
formattedValue = pn.getNumber('rfc3966'); // -> 'tel:+46-70-712-34-56'
|
formattedValue = pn.number.rfc3966; // -> 'tel:+46-70-712-34-56'
|
||||||
break;
|
break;
|
||||||
case 'significant':
|
case 'significant':
|
||||||
formattedValue = pn.getNumber('significant'); // -> '707123456'
|
formattedValue = pn.number.significant; // -> '707123456'
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import { PhoneUtilManager } from './PhoneUtilManager.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../types/index.js').RegionCode} RegionCode
|
* @typedef {import('../types/index.js').RegionCode} RegionCode
|
||||||
* @typedef {* & import('awesome-phonenumber').default} AwesomePhoneNumber
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -17,17 +16,17 @@ export function parsePhoneNumber(viewValue, { regionCode }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line prefer-destructuring
|
// eslint-disable-next-line prefer-destructuring
|
||||||
const PhoneNumber = /** @type {AwesomePhoneNumber} */ (PhoneUtilManager.PhoneUtil);
|
const AwesomePhoneNumber = PhoneUtilManager.PhoneUtil;
|
||||||
const regex = /[+0-9]+/gi;
|
const regex = /[+0-9]+/gi;
|
||||||
const strippedViewValue = viewValue.match(regex)?.join('');
|
const strippedViewValue = viewValue.match(regex)?.join('');
|
||||||
let pn;
|
let pn;
|
||||||
try {
|
try {
|
||||||
pn = PhoneNumber(strippedViewValue, regionCode);
|
pn = AwesomePhoneNumber.parsePhoneNumber(strippedViewValue, { regionCode });
|
||||||
// eslint-disable-next-line no-empty
|
// eslint-disable-next-line no-empty
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|
||||||
if (pn) {
|
if (pn) {
|
||||||
return pn.getNumber('e164');
|
return pn.number.e164;
|
||||||
}
|
}
|
||||||
|
|
||||||
return viewValue;
|
return viewValue;
|
||||||
|
|
|
||||||
|
|
@ -20,15 +20,15 @@ function hasFeedback(modelValue, regionCode) {
|
||||||
if (regionCode && modelValue?.length >= 4 && modelValue?.length <= 16) {
|
if (regionCode && modelValue?.length >= 4 && modelValue?.length <= 16) {
|
||||||
let pn;
|
let pn;
|
||||||
try {
|
try {
|
||||||
pn = PhoneNumber(modelValue, regionCode);
|
pn = PhoneNumber.parsePhoneNumber(modelValue, { regionCode });
|
||||||
invalidCountryCode = pn.g.regionCode !== regionCode;
|
invalidCountryCode = pn.regionCode !== regionCode;
|
||||||
if (invalidCountryCode) {
|
if (invalidCountryCode) {
|
||||||
return 'invalid-country-code';
|
return 'invalid-country-code';
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line no-empty
|
// eslint-disable-next-line no-empty
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
// too-short/too-long info seems to be not there (we get 'is-possible'?)
|
// too-short/too-long info seems to be not there (we get 'is-possible'?)
|
||||||
const enumValue = !pn.isValid() ? pn.g.possibility : false;
|
const enumValue = !pn.valid ? pn.possibility : false;
|
||||||
if (enumValue === 'is-possible') {
|
if (enumValue === 'is-possible') {
|
||||||
return 'unknown';
|
return 'unknown';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { PhoneNumber, PhoneUtilManager } from '@lion/ui/input-tel.js';
|
||||||
import { mockPhoneUtilManager, restorePhoneUtilManager } from '@lion/ui/input-tel-test-helpers.js';
|
import { mockPhoneUtilManager, restorePhoneUtilManager } from '@lion/ui/input-tel-test-helpers.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {* & import('awesome-phonenumber').default} AwesomePhoneNumber
|
* @typedef {* & import('awesome-phonenumber')} AwesomePhoneNumber
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// For enum output, see: https://www.npmjs.com/package/awesome-phonenumber
|
// For enum output, see: https://www.npmjs.com/package/awesome-phonenumber
|
||||||
|
|
@ -24,6 +24,7 @@ describe('PhoneNumber validation', () => {
|
||||||
expect(validator.execute('foo', 'NL')).to.equal('unknown');
|
expect(validator.execute('foo', 'NL')).to.equal('unknown');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: this changed after awesome-phonenumber v4. Skip for now, look into this later
|
||||||
it('is invalid when wrong country code is entered, returns "invalid-country-code"', () => {
|
it('is invalid when wrong country code is entered, returns "invalid-country-code"', () => {
|
||||||
const validator = new PhoneNumber();
|
const validator = new PhoneNumber();
|
||||||
// 32 is BE region code
|
// 32 is BE region code
|
||||||
|
|
@ -47,12 +48,13 @@ describe('PhoneNumber validation', () => {
|
||||||
|
|
||||||
it('handles validation via awesome-phonenumber', () => {
|
it('handles validation via awesome-phonenumber', () => {
|
||||||
const validator = new PhoneNumber();
|
const validator = new PhoneNumber();
|
||||||
const spy = sinon.spy(PhoneUtilManager, 'PhoneUtil');
|
// @ts-ignore
|
||||||
|
const spy = sinon.spy(PhoneUtilManager.PhoneUtil, 'parsePhoneNumber');
|
||||||
validator.execute('0123456789', 'NL');
|
validator.execute('0123456789', 'NL');
|
||||||
expect(spy).to.have.been.calledOnce;
|
expect(spy).to.have.been.calledOnce;
|
||||||
expect(spy.lastCall.args[1]).to.equal('NL');
|
expect(spy.lastCall.args[1]).to.eql({ regionCode: 'NL' });
|
||||||
validator.execute('0123456789', 'DE');
|
validator.execute('0123456789', 'DE');
|
||||||
expect(spy.lastCall.args[1]).to.equal('DE');
|
expect(spy.lastCall.args[1]).to.eql({ regionCode: 'DE' });
|
||||||
spy.restore();
|
spy.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -75,7 +77,8 @@ describe('PhoneNumber validation', () => {
|
||||||
|
|
||||||
it('waits for the lib to be loaded before execution completes when still in async mode', async () => {
|
it('waits for the lib to be loaded before execution completes when still in async mode', async () => {
|
||||||
const validator = new PhoneNumber();
|
const validator = new PhoneNumber();
|
||||||
const spy = sinon.spy(PhoneUtilManager, 'PhoneUtil');
|
// @ts-ignore
|
||||||
|
const spy = sinon.spy(PhoneUtilManager.PhoneUtil, 'parsePhoneNumber');
|
||||||
const validationResult = validator.execute('061234', 'NL');
|
const validationResult = validator.execute('061234', 'NL');
|
||||||
expect(validationResult).to.be.instanceOf(Promise);
|
expect(validationResult).to.be.instanceOf(Promise);
|
||||||
expect(spy).to.not.have.been.called;
|
expect(spy).to.not.have.been.called;
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@
|
||||||
"@open-wc/dedupe-mixin": "^1.3.1",
|
"@open-wc/dedupe-mixin": "^1.3.1",
|
||||||
"@open-wc/scoped-elements": "^2.1.3",
|
"@open-wc/scoped-elements": "^2.1.3",
|
||||||
"autosize": "4.0.2",
|
"autosize": "4.0.2",
|
||||||
"awesome-phonenumber": "^3.0.1",
|
"awesome-phonenumber": "^4.0.0",
|
||||||
"ibantools": "^2.2.0",
|
"ibantools": "^2.2.0",
|
||||||
"lit": "^2.4.0",
|
"lit": "^2.4.0",
|
||||||
"singleton-manager": "^1.6.1"
|
"singleton-manager": "^1.6.1"
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
diff --git a/node_modules/awesome-phonenumber/package.json b/node_modules/awesome-phonenumber/package.json
|
|
||||||
index 391577c..5a5ec22 100644
|
|
||||||
--- a/node_modules/awesome-phonenumber/package.json
|
|
||||||
+++ b/node_modules/awesome-phonenumber/package.json
|
|
||||||
@@ -15,6 +15,7 @@
|
|
||||||
"types": "./index.d.ts",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
+ "types": "./index.d.ts",
|
|
||||||
"require": "./index.js",
|
|
||||||
"default": "./index-esm.mjs"
|
|
||||||
},
|
|
||||||
Loading…
Reference in a new issue