@ desource/ phone- mask (英语)
核心TypeScript 库,用于用 Google 的 libphone 数字数据掩盖国际电话号码
框架-可知手机口罩库 与Google的libphone数字数据库保持最新.
升级到 2. 0. 0 之前,审查 1.7.0的移徙 用于断开更改和需要更新.
* 特性
- 🌍 240多个国家 有准确的口罩和拨号码
- 🔄 自动符号 从 Google 的 libphone 编号
- 🪶 小声 - 根条目为 6.1 KB 变焦, 2.9 KB gziped, 2.3 KB brotli
- 🌳 树能震动 ——只导入您需要的
- 🔧 类型脚本 ——已打满字
- 🎯 零依赖关系
* 安装
npm install @desource/phone-mask
# or
yarn add @desource/phone-mask
# or
pnpm add @desource/phone-mask
导入路径
根项包含国家元数据并遮盖数据. 显示格式化、低级格式化、输入处理、检测和工具辅助工具 kit 子路径.
import { MasksFullMapEn, type CountryKey } from '@desource/phone-mask';
import { formatPhone, createPhoneFormatter, formatDigitsWithMap } from '@desource/phone-mask/kit';
分发格式
包件进口采用未消减的无害环境管理或通用JS;应用程序捆绑商处理打树机和打树机。 两个条目都包含每个模块格式的TypeScript声明.
| 使用大小写 | 根项 | Kit 条目 |
|---|---|---|
| 无害环境管理,包括本地浏览器模块 | dist/esm/index.js | dist/esm/kit.js |
| 常见JS | dist/phone-mask.cjs | dist/kit.cjs |
| 浏览器全局, 可读 | dist/phone-mask.umd.js | dist/kit.umd.js |
| 浏览器全局, 已修改 | dist/phone-mask.umd.min.js | dist/kit.umd.min.js |
对于没有构建步骤的浏览器使用,加载两个全局器,将国家数据与格式化帮助器合并:
<script src="https://cdn.jsdelivr.net/npm/@desource/phone-mask/dist/phone-mask.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@desource/phone-mask/dist/kit.umd.min.js"></script>
<script>
const result = phoneMaskKit.formatDigitsWithMap(phoneMask.MasksBaseMap.US[0], '2025551234');
console.log(result.display); // "+1 202-555-1234"
</script>
将两个 CDN URL 绑入生产中相同的软件包版本 。 UNPKG支持相同的文件路径.
QQ 快速启动
显示格式
import { formatPhone } from '@desource/phone-mask/kit';
formatPhone('+12345678888'); // '+1 234 567 8888'
formatPhone('2345678888', 'US', { code: false, flag: true }); // '🇺🇸 234 567 8888'
见 formatPhone 选项和支持的输入格式.
基本格式
import { MasksBaseMap, MasksMap } from '@desource/phone-mask';
import { formatDigitsWithMap } from '@desource/phone-mask/kit';
// Get US mask with country code prefix
const prefixUsMask = MasksBaseMap.US;
// ["+1 ###-###-####"]
// Format digits
const result = formatDigitsWithMap(prefixUsMask[0], '2025551234');
console.log(result.display); // "+1 202-555-1234"
console.log(result.map); // [-1, -1, -1, 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, 9]
// Get US mask without country code prefix
const usMask = MasksMap.US.mask;
// ["###-###-####"]
// Format digits without country code
const resultNoCode = formatDigitsWithMap(usMask[0], '2025551234');
console.log(resultNoCode.display); // "202-555-1234"
console.log(resultNoCode.map); // [0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, 9]
与国别数据合作
import { MasksFullMapEn, type MaskFull } from '@desource/phone-mask';
// Access country data
const us = MasksFullMapEn.US;
console.log(us.name); // "United States"
console.log(us.code); // "+1"
console.log(us.mask); // ["###-###-####"]
console.log(us.flag); // "🇺🇸"
多个遮罩变体
一些国家有多种口罩格式:
import { MasksFullMapEn } from '@desource/phone-mask';
const gb = MasksFullMapEn.GB;
console.log(gb.mask);
// [
// "#### ######",
// "### ### ####",
// "## #### ####"
// ]
本地化的国名
import { MasksFullMap } from '@desource/phone-mask';
// Get localized names
const germanMap = MasksFullMap('de');
console.log(germanMap.US.name); // "Vereinigte Staaten"
const frenchMap = MasksFullMap('fr');
console.log(frenchMap.US.name); // "États-Unis"
工具函数
import { countPlaceholders, removeCountryCodePrefix, pickMaskVariant, extractDigits } from '@desource/phone-mask/kit';
// Count placeholder digits
const count = countPlaceholders('+1 ###-###-####');
// 10
// Remove country code prefix
const stripped = removeCountryCodePrefix('+1 ###-###-####');
// "###-###-####"
// Pick best mask variant for digit count
const variants = ['+44 #### ######', '+44 ### ### ####'];
const best = pickMaskVariant(variants, 10);
// "+44 #### ######"
// Extract only digits from string
const digits = extractDigits('+1 (202) 555-1234');
// "12025551234"
对照国家规则审定编号
使用 createPhoneFormatter() 对照特定国家的口罩变体验证长度.
以下的食谱接受当地编号或带有所选国家调用代码的国际编号. 它们缩短了超数数字,以便与框架输入相匹配。 使用 country.code 从电话值中删除已知的呼叫代码; removeCountryCodePrefix() 用于口罩模板.
import { MasksFullMapEn, type CountryKey } from '@desource/phone-mask';
import { createPhoneFormatter, extractDigits } from '@desource/phone-mask/kit';
function validateForCountry(input: string, id: CountryKey) {
const country = MasksFullMapEn[id];
const value = input.trim();
if (!country || (value.startsWith('+') && !value.startsWith(country.code))) {
return {
digits: '',
display: '',
isComplete: false
};
}
const formatter = createPhoneFormatter(country);
const inputWithoutCode = value.startsWith(country.code) ? value.slice(country.code.length) : value;
const digits = extractDigits(inputWithoutCode, formatter.getMaxDigits());
return {
digits,
display: formatter.formatDisplay(digits),
isComplete: formatter.isComplete(digits)
};
}
validateForCountry('+1 (202) 555-1234', 'US');
// { digits: "2025551234", display: "202-555-1234", isComplete: true }
validateForCountry('+12025551234', 'US');
// { digits: "2025551234", display: "202-555-1234", isComplete: true }
后端处理的 Raw 数字
使用原始数字进行存储和运输。 只保留客户端格式化 .
import { MasksFullMapEn, type CountryKey } from '@desource/phone-mask';
import { createPhoneFormatter, extractDigits } from '@desource/phone-mask/kit';
function buildPhonePayload(input: string, id: CountryKey) {
const country = MasksFullMapEn[id];
const value = input.trim();
if (!country || (value.startsWith('+') && !value.startsWith(country.code))) return null;
const formatter = createPhoneFormatter(country);
const inputWithoutCode = value.startsWith(country.code) ? value.slice(country.code.length) : value;
const localDigits = extractDigits(inputWithoutCode, formatter.getMaxDigits());
return {
country: id,
phoneDigits: localDigits, // canonical backend field
phoneE164: `${country.code}${localDigits}` // optional: with dialing prefix
};
}
自定义 Regex + 元数据( 区域/ Carrier 前缀)
将 Phone Mask 元数据与区域特定的regex 规则合并:
import { MasksFullMapEn, type CountryKey } from '@desource/phone-mask';
import { createPhoneFormatter, extractDigits } from '@desource/phone-mask/kit';
const tenantCarrierRules: Partial<Record<CountryKey, RegExp>> = {
BR: /^(11|21|31)\d{8,9}$/,
IN: /^(98|99)\d{8}$/
};
function validateWithCarrierRule(input: string, id: CountryKey): boolean {
const country = MasksFullMapEn[id];
const value = input.trim();
if (!country || (value.startsWith('+') && !value.startsWith(country.code))) return false;
const formatter = createPhoneFormatter(country);
const inputWithoutCode = value.startsWith(country.code) ? value.slice(country.code.length) : value;
const digits = extractDigits(inputWithoutCode, formatter.getMaxDigits());
const carrierRule = tenantCarrierRules[id];
if (!formatter.isComplete(digits)) return false;
return carrierRule ? carrierRule.test(digits) : true;
}
多租户:租户Id 默认国家+特定租户审定规则
import { MasksFullMapEn, type CountryKey } from '@desource/phone-mask';
import { createPhoneFormatter, extractDigits } from '@desource/phone-mask/kit';
type TenantPolicy = {
defaultCountry: CountryKey;
prefixRule?: RegExp;
};
const TENANT_POLICIES: Record<string, TenantPolicy> = {
acme: { defaultCountry: 'US', prefixRule: /^(202|303)\d{7}$/ },
globex: { defaultCountry: 'GB', prefixRule: /^7\d{9}$/ }
};
function createTenantPhoneService(tenantId: string) {
const policy = TENANT_POLICIES[tenantId] ?? { defaultCountry: 'US' as const };
const id = policy.defaultCountry;
const country = MasksFullMapEn[id];
const formatter = createPhoneFormatter(country);
return {
defaultCountry: id,
format(input: string) {
const value = input.trim();
if (value.startsWith('+') && !value.startsWith(country.code)) return input;
const inputWithoutCode = value.startsWith(country.code) ? value.slice(country.code.length) : value;
const digits = extractDigits(inputWithoutCode, formatter.getMaxDigits());
return formatter.formatDisplay(digits);
},
validate(input: string) {
const value = input.trim();
if (value.startsWith('+') && !value.startsWith(country.code)) return false;
const inputWithoutCode = value.startsWith(country.code) ? value.slice(country.code.length) : value;
const digits = extractDigits(inputWithoutCode, formatter.getMaxDigits());
const complete = formatter.isComplete(digits);
const prefixOk = policy.prefixRule ? policy.prefixRule.test(digits) : true;
return complete && prefixOk;
}
};
}
API 参考
类型
// Country ISO 3166-1 alpha-2 code
type CountryKey = 'US' | 'GB' | 'DE' | ... // 240+ countries
// Mask interfaces
interface MaskBase {
id: CountryKey;
mask: Array<string>;
}
interface Mask extends MaskBase {
code: string;
}
interface MaskWithFlag extends Mask {
flag: string;
}
interface MaskFull extends MaskWithFlag {
name: string;
}
type MaskBaseMap = Record<CountryKey, Array<string>>;
type MaskMap = Record<CountryKey, Omit<Mask, 'id'>>;
type MaskWithFlagMap = Record<CountryKey, Omit<MaskWithFlag, 'id'>>;
type MaskFullMap = Record<CountryKey, Omit<MaskFull, 'id'>>;
根条目导出
导入掩码数据和国家类型 @desource/phone-mask。 。 。 .
MasksBaseMap 打开 MasksBase
基本国家口罩,包括国家代码前缀(轻量级版):
const MasksBaseMap: MaskBaseMap;
const MasksBase: MaskBase[];
使用这些来获取带有国家代码前缀的生口罩. 说明: 一些帮助者功能可能会期望没有国家代码的口罩.
MasksMap 打开 Masks
以国家代码作为单独财产的面具:
const MasksMap: MaskMap;
const Masks: Mask[];
MasksWithFlagMap 打开 MasksWithFlag
带有国家代码和旗帜的面具:
const MasksWithFlagMap: MaskWithFlagMap;
const MasksWithFlag: MaskWithFlag[];
MasksFullMapEn 打开 MasksFullEn
英文国名完整的国家数据:
const MasksFullMapEn: MaskFullMap;
const MasksFullEn: MaskFull[];
MasksFullMap(locale: string) 打开 MasksFull(locale: string)
获得带有本地化国名的完整国家数据:
function MasksFullMap(locale: string): MaskFullMap;
function MasksFull(locale: string): MaskFull[];
支持的地方数字 : en, (中文(简体) ), de, (中文(简体) ), fr, (中文(简体) ), es, (中文(简体) ), it, (中文(简体) ), pt, (中文(简体) ), ru, (中文(简体) ), zh, (中文(简体) ), ja, (中文(简体) ), ko还有更多.
getFlagEmoji(countryCode: CountryKey)
获取国家代码的旗下emoji :
function getFlagEmoji(countryCode: CountryKey): string;
Kit 子路径导出
进口材料、输入处理、检测和工具助手 @desource/phone-mask/kit。 。 。 .
// Count # placeholders in mask
function countPlaceholders(mask: string): number;
// Remove country code prefix from mask
function removeCountryCodePrefix(mask: string): string;
// Pick best mask variant for digit length
function pickMaskVariant(masks: string[], digitLength: number): string;
// Extract digits from any string
function extractDigits(value: string, maxLength?: number): string;
// Detect a complete international number from current masks
function detectCountryFromPhone(value: string): CountryKey | undefined;
// Format digits according to template
function formatDigitsWithMap(value: string, digits: string): { display: string; map: number[] };
detectCountryFromPhone 需要领导 +。它首先匹配精确的格式,然后返回到
呼叫代码和数字数 排除代码。 共享匹配使用调用代码生成的默认国家;
例如,未格式化 +1 数字默认为美国。 不支持的语法,未知的调用代码,以及
未匹配的长度返回 undefined检测使用口罩,而不是分配前缀或数字验证.
import { detectCountryFromPhone } from '@desource/phone-mask/kit';
detectCountryFromPhone('+7 123 456 7788'); // 'KZ': unique mask
detectCountryFromPhone('+71234567788'); // 'RU': shared length, default country
detectCountryFromPhone('1234567788'); // undefined: no international prefix
processPaste 返回可选选项 country 当检测成功时。 在
已返回 newDigits,不包括调用代码。 检测到的国际粘贴取代整个输入并放置
端部有护身符,而上所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出. 其他粘贴保持正常
选择和插入行为.
formatPhone(value, country?, options?)
使用国家口罩组格式化一个显示的电话号码,以空格分隔. 这个纯函数在浏览器和SSR期间有效. React, Vue, and Svelte再导出此功能,用于模板和JSX. 角质 PhonePipe 请各位代表出席。 每个框架一揽子方案也通过下列方式揭露了这一点: /core 子路径.
import { formatPhone, type PhoneFormatOptions } from '@desource/phone-mask/kit';
formatPhone('+12345678888'); // '+1 234 567 8888'
formatPhone('2345678888', 'US'); // '+1 234 567 8888'
formatPhone('+1 (234) 567-8888', 'US', { code: false }); // '234 567 8888'
formatPhone('+12345678888', 'US', { flag: true }); // '🇺🇸 +1 234 567 8888'
formatPhone('234 567 8888', 'US', { code: false, flag: true }); // '🇺🇸 234 567 8888'
interface PhoneFormatOptions {
readonly code?: boolean; // Include the calling code; defaults to true.
readonly flag?: boolean; // Prepend the flag emoji; defaults to false.
}
function formatPhone(
value: string | null | undefined,
country?: CountryKey | null,
options?: PhoneFormatOptions
): string;
只有一个明确 + 调用代码被删除; 空位数字作为没有调用代码的数字处理. 通过这些值的ISO国家代码. 没有国家,检测需要完整的国际编号,并使用口罩形状,调用代码,长度. 共享匹配使用默认国家, 如 US +1;检测不检查区域代码分配。 过 undefined 或者说 null 作为将检测与选择相结合的国家.
被供应国在调用代码时优先,所以 formatPhone('+12345678888', 'CA', { flag: true }) 保留了加拿大国旗。 如果代码冲突, 成功检测优先 : formatPhone('+442079460958', 'US') 返回时 '+44 2079 460958',不成功的检测保留了原值.
保留了重要的领先零。 空的,只有白空间, null,以及 undefined 数值返回 ''。不支持的国家、无效字符、扩展和超过所选掩码长度的值保持不变。 该函数不会推断树干前缀或验证是否指定了数字. 将结果显示为文本, 如任何用户提供的值 .
使用大小写
自定义输入格式
import { MasksFullMapEn } from '@desource/phone-mask';
import { formatDigitsWithMap, extractDigits } from '@desource/phone-mask/kit';
function formatPhoneInput(value: string, countryCode: string = 'US') {
const country = MasksFullMapEn[countryCode];
const mask = country?.mask[0];
if (!mask) return value;
const digits = extractDigits(value);
return `${country.code} ${formatDigitsWithMap(mask, digits).display}`;
}
// Usage
const formatted = formatPhoneInput('2025551234', 'US');
// "+1 202-555-1234"
电话号码验证
import { MasksFullMapEn } from '@desource/phone-mask';
import { countPlaceholders } from '@desource/phone-mask/kit';
function isValidPhoneLength(digits: string, country: string): boolean {
const masks = MasksFullMapEn[country]?.mask;
if (!masks) return false;
const validLengths = masks.map((m) => countPlaceholders(m));
return validLengths.includes(digits.length);
}
// Usage
isValidPhoneLength('2025551234', 'US'); // true (10 digits)
isValidPhoneLength('202555', 'US'); // false (too short)
建设国家选择器
import { MasksFullEn, type CountryKey, type MaskFull } from '@desource/phone-mask';
type CountryOption = Omit<MaskFull, 'mask'>;
function getCountryOptions(): CountryOption[] {
return MasksFullEn.map((data) => ({
id: data.id,
name: data.name,
code: data.code,
flag: data.flag
}));
}
// Usage
const countries = getCountryOptions();
// [
// { id: 'US', name: 'United States', code: '+1', flag: '🇺🇸' },
// { id: 'GB', name: 'United Kingdom', code: '+44', flag: '🇬🇧' },
// ...
// ]
正在获取旗舰 Emojis
import { getFlagEmoji } from '@desource/phone-mask';
// Get flag emoji for country code
const flag = getFlagEmoji('US'); // "🇺🇸"
数据更新
库同步到 谷歌的手机号码 通过自动化工作流程。 要手动更新 :
pnpm gen
获取最新数据并重生 data.json。 。 。 .
此更新生成了软件包使用的元数据文件( U)src/data.json, (中文(简体) ), src/data.min.js,以及 src/data-types.ts) (中文(简体) ).
QQ 套装大小
将包装的包裹装入真正的消费者建筑中
| 消费者进口 | 大小( 最小) | 击出 | 布罗特利 |
|---|---|---|---|
import * as PhoneMask from '@desource/phone-mask' | 6.09 KB (韩语) | 2.86 KB (韩语) | 2.30 KB (韩语) |
import { MasksFullMapEn } from '@desource/phone-mask' | 5.75 KB (韩语) | 2.67 KB (韩语) | 2.13 KB (韩语) |
import * as Kit from '@desource/phone-mask/kit' | 13.28 KB (韩语) | 5.83 KB (韩语) | 4.90 千兆贝 |
import { createPhoneFormatter } from '@desource/phone-mask/kit' | 1.03 KB (韩语) | 0.59 KB (韩语) | 0.53 KB (韩语) |
import { formatDigitsWithMap } from '@desource/phone-mask/kit' | 0.25 KB (韩语) | 0.21 千兆贝 | 0.18 KB (韩语) |
import { extractDigits } from '@desource/phone-mask/kit' | 0.08 KB (韩语) | 0.10 KB (韩语) | 0.08 KB (韩语) |
import { getCountry } from '@desource/phone-mask/kit' | 5.84 KB (韩语) | 2.72 KB (韩语) | 2.18 KB (韩语) |
根项包含国家元数据并遮盖数据. 使用 @desource/phone-mask/kit 当您需要显示格式化、低级格式化、输入处理、检测或工具辅助工具时。 依赖数据帮助者, 如 getCountry 包括口罩数据;纯formatter和输入助手树-震到小的独立捆绑.
有关软件包
- @ desource/ phone- mask- angular (英语) ——角构件+指令+管子+服务
- @ desource/ phone- mask- react ——反应组件+钩
- @ desource/ phone- massk- svelte (英语) − Svelte 组件 + 可相容 + 动作 + 附加
- @ desource/ phone- mask- vue − Vue 3 组件 + 可相容 + 指令
- @ desource/ phone- mask- nuxt - 努克特模块
许可证
麻省理工学院 2026 来源实验室
捐款
见 贡献指南 用于开发、测试和出版检查.