@yext/phonenumber-util 0.2.0 β†’ 0.2.2

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/.husky/pre-commit CHANGED
@@ -3,4 +3,6 @@
3
3
 
4
4
  npx lint-staged
5
5
  npm run format
6
- npx vitest run --coverage
6
+ npx vitest run --coverage
7
+ npm run make-badges
8
+ npx generate-license-file --input package.json --output THIRD-PARTY-NOTICES --overwrite
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  Utility for extracting and validating phone numbers. Extracts an array of phone numbers from an inputted string, validates that these numbers appear genuine and provide data about those phone numbers.
2
2
 
3
+ [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) ![Statements](https://img.shields.io/badge/statements-100%25-brightgreen.svg?style=flat) ![Branches](https://img.shields.io/badge/branches-100%25-brightgreen.svg?style=flat) ![Functions](https://img.shields.io/badge/functions-100%25-brightgreen.svg?style=flat) ![Lines](https://img.shields.io/badge/lines-100%25-brightgreen.svg?style=flat)
4
+
3
5
  ### Scripts
4
6
 
5
7
  #### Install dependencies
@@ -196,7 +198,7 @@ Example output for Arizona:
196
198
 
197
199
  ```javascript
198
200
  import { findTimeFromAreaCode } from '@yext/phonenumber-util/geo';
199
- findTimeFromAreaCode('250');
201
+ findTimeFromAreaCode('250', date); // A date object is optional, defaulting to the current time.
200
202
  ```
201
203
 
202
204
  Example output for British Columbia:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yext/phonenumber-util",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "author": "bajohnson@hearsaycorp.com",
5
5
  "license": "BSD-3-Clause",
6
6
  "description": "Utility for extracting and validating phone numbers",
@@ -21,14 +21,17 @@
21
21
  "format": "prettier --write **/*.js **/__tests__/*.js",
22
22
  "test": "TZ=America/Los_Angeles vitest",
23
23
  "build": "node -e \"console.log('No build script for vanilla JS')\"",
24
- "prepare": "husky"
24
+ "prepare": "husky",
25
+ "make-badges": "istanbul-badges-readme"
25
26
  },
26
27
  "devDependencies": {
27
28
  "@eslint/js": "^9.7.0",
28
29
  "@vitest/coverage-v8": "^2.1.1",
29
30
  "eslint": "^9.7.0",
31
+ "generate-license-file": "^3.5.1",
30
32
  "globals": "^15.8.0",
31
33
  "husky": "^9.1.5",
34
+ "istanbul-badges-readme": "^1.9.0",
32
35
  "lint-staged": "^15.2.10",
33
36
  "prettier": "^3.3.3",
34
37
  "vitest": "^2.1.1"
@@ -220,20 +220,29 @@ describe('Phone number pretty formatting', () => {
220
220
  format: findPhoneFormat({ regionCode: '57', e164: '+573211234567' }),
221
221
  },
222
222
  germany: {
223
- e164: '+49 170 87654321',
223
+ e164: '+4917087654321',
224
224
  regionCode: '49',
225
225
  format: findPhoneFormat({ regionCode: '49', e164: '+4917087654321' }),
226
226
  },
227
227
  germanyAlt: {
228
- e164: '+49 170 8765432',
228
+ e164: '+491708765432',
229
229
  regionCode: '49',
230
230
  format: findPhoneFormat({ regionCode: '49', e164: '+491708765432' }),
231
231
  },
232
+ norwayUnexpected: {
233
+ e164: '+47174087654',
234
+ regionCode: '47',
235
+ format: findPhoneFormat({ regionCode: '47', e164: '+471740876543' }),
236
+ },
232
237
  };
233
238
 
234
239
  expect(formatPhoneNumber(testNumbers.nullCase)).toBe(null);
235
240
  expect(formatPhoneNumber(testNumbers.us)).toBe('(310) 349-6200');
236
241
  expect(formatPhoneNumber(testNumbers.colombia)).toBe('+57 321 123 4567');
237
242
  expect(formatPhoneNumber(testNumbers.germanyAlt)).toBe('+49 17 08765432');
243
+ // This looks like a Norwegian number, but doesn't match a known format. In this case, we'll return a sanitized generic format.
244
+ expect(formatPhoneNumber(testNumbers.norwayUnexpected)).toBe(
245
+ '+47174087654',
246
+ );
238
247
  });
239
248
  });
@@ -37,6 +37,27 @@ const seattlePhone = {
37
37
  },
38
38
  };
39
39
 
40
+ const portlandPhone = {
41
+ areaCodeHasMultipleTimezones: false,
42
+ daylightSavings: true,
43
+ estimatedTime: false,
44
+ isQuietHours: false,
45
+ isTCPAQuietHours: false,
46
+ localTime24Hour: '08:00:00',
47
+ localTimeReadable: '8:00:00 AM',
48
+ stateHasMultipleTimezones: true,
49
+ timezoneOffset: '-07:00',
50
+ state: {
51
+ name: 'Oregon',
52
+ code: 'OR',
53
+ },
54
+ region: {
55
+ name: 'United States',
56
+ code: 'US',
57
+ flag: 'πŸ‡ΊπŸ‡Έ',
58
+ },
59
+ };
60
+
40
61
  const arizonaPhoneJul = {
41
62
  areaCodeHasMultipleTimezones: false,
42
63
  daylightSavings: true,
@@ -250,6 +271,9 @@ describe('Provides general time information for the given phone number (US and C
250
271
  expect(
251
272
  findTimeFromAreaCode('206', new Date('2024-07-15T08:00:00')),
252
273
  ).toEqual(seattlePhone);
274
+ expect(
275
+ findTimeFromAreaCode('503', new Date('2024-07-15T08:00:00')),
276
+ ).toEqual(portlandPhone);
253
277
  expect(
254
278
  findTimeFromAreaCode('928', new Date('2024-07-15T08:00:00')),
255
279
  ).toEqual(arizonaPhoneJul);
@@ -21,6 +21,7 @@ export const AREA_CODE_LIST = [
21
21
  '223',
22
22
  '224',
23
23
  '225',
24
+ '226',
24
25
  '257',
25
26
  '228',
26
27
  '229',
package/src/base.js CHANGED
@@ -234,18 +234,6 @@ export const getPhoneParts = (phoneNumber) => {
234
234
  phoneParts.e164 = formatPhoneNumberForE164(phoneParts);
235
235
  phoneParts.format = findPhoneFormat(phoneParts);
236
236
  phoneParts.formattedNumber = formatPhoneNumber(phoneParts);
237
-
238
- // If there are left over x's, the formatting ran into something unexpected.
239
- // This may be ok depending on the region and their phone number formats.
240
- // But it does mean we don't want to display this number.
241
- if (
242
- phoneParts.formattedNumber &&
243
- phoneParts.formattedNumber.indexOf('x') !== -1
244
- ) {
245
- // Since `rawNumber` isn't sanitized, we'll use a simple format that we
246
- // are assured to be safe.
247
- phoneParts.formattedNumber = strippedPhoneNumber;
248
- }
249
237
  }
250
238
 
251
239
  return phoneParts;
@@ -353,16 +341,26 @@ export const findPhoneFormat = ({ regionCode, e164 }) => {
353
341
  * @param {Object} params - The parameters for formatting the phone number.
354
342
  * @param {string} params.format - The desired format for the phone number. Example: `(xxx) xxx-xxxx`.
355
343
  * @param {string} params.e164 - The E.164 formatted phone number to format. Example: `+12065551234`.
344
+ * @param {string} params.regionCode - The region code of the phone number. Example, the US would be "1".
356
345
  * @returns {string|null} The formatted phone number, or null if the E.164 number or format is not provided.
357
346
  */
358
- export const formatPhoneNumber = ({ format, e164 }) => {
347
+ export const formatPhoneNumber = ({ format, e164, regionCode }) => {
359
348
  let formattedNumber = '';
360
349
 
361
350
  if (e164 && format) {
362
351
  // Remove the leading '+' and let the format handle it.
363
- const strippedPhone = e164.replace(/\D/g, '');
352
+ const strippedPhone = e164.replace(/\+/g, '');
364
353
  let phoneIndex = strippedPhone.length - 1;
365
354
 
355
+ // The US / NANP rarely includes region code prefix when sharing numbers. Other regions often do, so we'll have a special condition to allow ignoring of the region code for region 1.
356
+ // For other regions, we'll return the stripped number to safely display the presumed good number that may be in a safe but not-ideal format.
357
+ if (
358
+ regionCode !== '1' &&
359
+ strippedPhone.length !== format.split('x').length - 1
360
+ ) {
361
+ return e164;
362
+ }
363
+
366
364
  // Traverse backward so we can omit country code in some formats (like US).
367
365
  for (let i = format.length; i >= 0; i--) {
368
366
  if (format[i]) {
package/src/geo.js CHANGED
@@ -186,7 +186,8 @@ export function findTimeFromAreaCode(areaCode, date = new Date()) {
186
186
  returnTime.areaCodeHasMultipleTimezones = false;
187
187
  }
188
188
  } else {
189
- returnTime.stateHasMultipleTimezones = false;
189
+ returnTime.stateHasMultipleTimezones =
190
+ !!STATES_WITH_MULTIPLE_TIMEZONES[stateName];
190
191
  returnTime.areaCodeHasMultipleTimezones = false;
191
192
  localOffset = STATE_TIMEZONES[stateName];
192
193
  }
package/src/phoneCodes.js CHANGED
@@ -389,6 +389,7 @@ export const AREA_CODES = {
389
389
  state: 'NS/PE',
390
390
  region: CANADA,
391
391
  },
392
+ 226: { name: 'Ontario', code: 'ON', region: CANADA },
392
393
  289: { name: 'Ontario', code: 'ON', region: CANADA },
393
394
  343: { name: 'Ontario', code: 'ON', region: CANADA },
394
395
  365: { name: 'Ontario', code: 'ON', region: CANADA },
package/vitest.config.js CHANGED
@@ -2,5 +2,8 @@ export default {
2
2
  test: {
3
3
  globals: true,
4
4
  environment: 'node',
5
+ coverage: {
6
+ reporter: ['json-summary'],
7
+ },
5
8
  },
6
9
  };