npm.io
2.0.0 • Published 3d ago

yup-phone

Licence
MIT
Version
2.0.0
Deps
1
Size
1.5 MB
Vulns
0
Weekly
0
Stars
239

yup-phone MIT License npm - yup-phone Tweet yup-phone validator

Build Status Commitizen friendly FOSSA Status Known Vulnerabilities Codacy Badge

Phone validation for Yup 0.32.11 and 1.x, powered by libphonenumber-js. Version 2 uses max metadata to validate digits as well as length, including fixed lines, mobiles, and service numbers. Yup remains external: the plugin registers on your application's Yup instance.

Install

npm install yup yup-phone
# Existing Yup 0.32 applications:
npm install yup@0.32.11 yup-phone@2

Use

import * as yup from 'yup';
import 'yup-phone';

yup.string().phone().required().isValidSync('9876543210'); // true
yup.string().phone('US').isValidSync('(541) 754-3010'); // true
yup.string().phone('IN', true).isValidSync('+1 345 9490088'); // false
yup.string().phone('IN', false).isValidSync('+1 345 9490088'); // true

CommonJS works with the same API:

const yup = require('yup');
require('yup-phone');

yup.string().phone('IN', true).isValidSync('+919876543210'); // true

phone(countryCode?: string, strict?: boolean, errorMessage?: string) returns the same schema type, preserving required/optional/nullable/context/default inference and chainable Yup methods. TypeScript users only need the side-effect import; remove obsolete @types/yup when using Yup's built-in types.

Argument Default Behavior
countryCode IN Country used to parse national numbers. International numbers retain their own calling code.
strict false When true, validate against the requested region's rules and calling code. Shared service ranges can be valid in multiple regions.
errorMessage Existing regional/general message Accepts Yup ${path} interpolation.
const schema = yup.object({
  phone: yup.string().phone('IN', true, '${path} is invalid').required(),
});

Compatibility with version 1

The original test file is unchanged. Version 2 retains the default India region, loose international validation, country-code string parameters, strict region rules, error messages, Yup casting, formatted numbers, extensions, and vanity numbers such as 1-800-FLOWERS. Missing or non-two-character country arguments fall back to India and disable strict region matching, as before. Unknown or lowercase two-character codes do not become an India fallback.

Empty strings, undefined, and null continue to fail the phone check, even when the schema is optional or nullable. PR #826 would change that contract and is not included. An application can conditionally apply phone() when a value is present if optional empty phone fields are required.

The new major release raises the runtime requirement from Node 9 to Node 18+ and targets modern browsers with ES2020 support. Development and release checks use Node 22/24 and current TypeScript. TypeScript consumer checks use an ES2020 library and skipLibCheck: false. Historical CJS and UMD filenames remain; the historical ESM .js filename is also shipped for bundlers. Native Node ESM uses the .mjs entry through conditional exports.

Phone-number assignments change over time. Updating libphonenumber-js updates external CJS/ESM metadata; CDN/UMD metadata changes when yup-phone is released. The Google reference comparison catches regressions across regions and number types but does not promise identical results for every input or freeze old numbering plans forever.

Common integration questions

The region is a default parsing region in loose mode. Use the second argument when the number must belong to that region:

yup.string().phone('DE').isValidSync('+919876543210'); // true
yup.string().phone('DE', true).isValidSync('+919876543210'); // false
yup.string().phone('US').isValidSync('2819129531'); // true

Pass a custom message as the third argument. To keep the default India region, use phone(undefined, false, 'Invalid phone number'); JavaScript does not support named arguments such as phone(errorMessage = '...').

To opt into optional empty fields while retaining the phone validator's legacy contract, apply it only when a value is present:

const optionalPhone = yup.lazy((value) =>
  value == null || value === ''
    ? yup.string().nullable()
    : yup.string().phone('US'),
);

// Place required first when its message should win for an empty string.
const requiredPhone = yup.string().required('Phone is required').phone('US');

If .phone is missing at runtime, import 'yup-phone' before constructing schemas and use one supported Yup instance. Version 2 declares Yup as a peer, ships augmentation declarations, and keeps registration as a side effect. Packed-package tests exercise Node, browser bundling, and TypeScript consumers.

Module formats

Consumer Entry
Node require dist/yup-phone.cjs.js
Node import / modern bundler dist/yup-phone.esm.mjs
TypeScript dist/index.d.ts
UMD / AMD / browser global dist/yup-phone.umd.js and .umd.min.js
unpkg / jsDelivr dist/yup-phone.umd.min.js

The UMD bundle includes phone metadata and expects an existing global yup, or an AMD/CommonJS yup dependency. Load Yup before the plugin in a script-tag application. Package metadata intentionally has no browser override, following PR #835, so web bundlers consume the external ESM/CJS dependency rather than silently choosing a bundled UMD snapshot. sideEffects: true keeps registration from being removed by tree shaking.

Benchmarks and verification

npm ci --ignore-scripts
npm run check
npm run test:baseline
npm run benchmark
npm audit --audit-level=low

The benchmark compares the frozen v1.3.2 adapter with the new adapter using the same Yup version and current Google reference metadata. It measures synchronous validation across valid, invalid, strict, formatted, extension, and vanity cases; fresh-process adapter import time; and raw/gzip artifact sizes. It alternates sample order and saves individual timings and environment/version details in benchmarks/results/latest.json and a readable report. BENCH_ITERATIONS and BENCH_SAMPLES control the run length. CPU timings are informational; CI enforces at least a 25% gzip reduction for the full UMD bundle against the v1 fixture.

The migration reduces the bundled browser footprint. Some input classes and cold CJS imports can be slower, so consult the measured report for your workload. Google is only a development/reference dependency and is excluded from the published package's production dependency graph.

CI runs the unchanged original tests, regression/reference checks, strict declaration checks, and actual packed CJS/ESM/UMD/AMD/TypeScript consumers against Yup 0.32.11, 1.0.0, and latest on Node 22/24, with Windows coverage. Weekly runs detect dependency/metadata drift. Audits and CodeQL cover security, and grouped Dependabot updates keep dependencies and pinned Actions current.

Releases

See release setup for the one-time npm trusted-publisher and GitHub Actions setup. Conventional commits drive Release Please version PRs, changelogs, v<major>.<minor>.<patch> tags, GitHub Releases, provenance-backed npm publication, and downloadable package/benchmark artifacts. The initial feat! migration advances the existing v1.3.2 line to v2.0.0, retaining both supported Yup major lines. Generated dist files are built and tested by CI and prepack; they are also checked into Git for direct repository consumers.

License

FOSSA Status

MIT.

Keywords