Release 202506041641
This commit is contained in:
@@ -3,6 +3,9 @@ import { parsePhoneNumberWithError } from 'libphonenumber-js'
|
||||
import { makeHelpersForOptions } from '../lib/makeHelpersForOptions'
|
||||
import { transformCase } from '../lib/strings'
|
||||
|
||||
import type { Assert } from '../lib/assert'
|
||||
import type { Equals } from 'ts-toolbelt/out/Any/Equals'
|
||||
|
||||
type ContactMethodInfo<T extends string | null | undefined = string> = {
|
||||
type: T
|
||||
label: string
|
||||
@@ -10,6 +13,7 @@ type ContactMethodInfo<T extends string | null | undefined = string> = {
|
||||
matcher: RegExp
|
||||
formatter: (match: RegExpMatchArray) => string | null
|
||||
icon: string
|
||||
urlType: string
|
||||
}
|
||||
|
||||
export const {
|
||||
@@ -22,9 +26,10 @@ export const {
|
||||
(type): ContactMethodInfo<typeof type> => ({
|
||||
type,
|
||||
label: type ? transformCase(type, 'title') : String(type),
|
||||
icon: 'ri:shield-fill',
|
||||
icon: 'ri:link',
|
||||
matcher: /(.*)/,
|
||||
formatter: ([, value]) => value ?? String(value),
|
||||
urlType: type ?? 'unknown',
|
||||
}),
|
||||
[
|
||||
{
|
||||
@@ -33,24 +38,37 @@ export const {
|
||||
matcher: /mailto:(.+)/,
|
||||
formatter: ([, value]) => value ?? 'Email',
|
||||
icon: 'ri:mail-line',
|
||||
urlType: 'email',
|
||||
},
|
||||
{
|
||||
type: 'telephone',
|
||||
label: 'Telephone',
|
||||
matcher: /tel:(.+)/,
|
||||
formatter: ([, value]) => {
|
||||
return value ? parsePhoneNumberWithError(value).formatInternational() : 'Telephone'
|
||||
try {
|
||||
return value ? parsePhoneNumberWithError(value).formatInternational() : 'Telephone'
|
||||
} catch (_error) {
|
||||
console.error(`Invalid telephone number: ${value ?? 'undefined'}`, _error)
|
||||
return value ?? 'Telephone'
|
||||
}
|
||||
},
|
||||
icon: 'ri:phone-line',
|
||||
urlType: 'telephone',
|
||||
},
|
||||
{
|
||||
type: 'whatsapp',
|
||||
label: 'WhatsApp',
|
||||
matcher: /^https?:\/\/(?:www\.)?wa\.me\/(.+)/,
|
||||
formatter: ([, value]) => {
|
||||
return value ? parsePhoneNumberWithError(value).formatInternational() : 'WhatsApp'
|
||||
try {
|
||||
return value ? parsePhoneNumberWithError(value).formatInternational() : 'WhatsApp'
|
||||
} catch (_error) {
|
||||
console.error(`Invalid WhatsApp number: ${value ?? 'undefined'}`, _error)
|
||||
return value ?? 'WhatsApp'
|
||||
}
|
||||
},
|
||||
icon: 'ri:whatsapp-line',
|
||||
urlType: 'url',
|
||||
},
|
||||
{
|
||||
type: 'telegram',
|
||||
@@ -58,6 +76,7 @@ export const {
|
||||
matcher: /^https?:\/\/(?:www\.)?t\.me\/(.+)/,
|
||||
formatter: ([, value]) => (value ? `t.me/${value}` : 'Telegram'),
|
||||
icon: 'ri:telegram-line',
|
||||
urlType: 'url',
|
||||
},
|
||||
{
|
||||
type: 'linkedin',
|
||||
@@ -65,6 +84,7 @@ export const {
|
||||
matcher: /^https?:\/\/(?:www\.)?linkedin\.com\/(?:in|company)\/(.+)/,
|
||||
formatter: ([, value]) => (value ? `in/${value}` : 'LinkedIn'),
|
||||
icon: 'ri:linkedin-box-line',
|
||||
urlType: 'url',
|
||||
},
|
||||
{
|
||||
type: 'x',
|
||||
@@ -72,6 +92,7 @@ export const {
|
||||
matcher: /^https?:\/\/(?:www\.)?x\.com\/(.+)/,
|
||||
formatter: ([, value]) => (value ? `@${value}` : 'X'),
|
||||
icon: 'ri:twitter-x-line',
|
||||
urlType: 'url',
|
||||
},
|
||||
{
|
||||
type: 'instagram',
|
||||
@@ -79,6 +100,7 @@ export const {
|
||||
matcher: /^https?:\/\/(?:www\.)?instagram\.com\/(.+)/,
|
||||
formatter: ([, value]) => (value ? `@${value}` : 'Instagram'),
|
||||
icon: 'ri:instagram-line',
|
||||
urlType: 'url',
|
||||
},
|
||||
{
|
||||
type: 'matrix',
|
||||
@@ -86,6 +108,7 @@ export const {
|
||||
matcher: /^https?:\/\/(?:www\.)?matrix\.to\/#\/(.+)/,
|
||||
formatter: ([, value]) => (value ? `#${value}` : 'Matrix'),
|
||||
icon: 'ri:hashtag',
|
||||
urlType: 'url',
|
||||
},
|
||||
{
|
||||
type: 'bitcointalk',
|
||||
@@ -93,6 +116,7 @@ export const {
|
||||
matcher: /^https?:\/\/(?:www\.)?bitcointalk\.org/,
|
||||
formatter: () => 'BitcoinTalk',
|
||||
icon: 'ri:btc-line',
|
||||
urlType: 'url',
|
||||
},
|
||||
{
|
||||
type: 'simplex',
|
||||
@@ -100,6 +124,7 @@ export const {
|
||||
matcher: /^https?:\/\/(?:www\.)?(simplex\.chat)\//,
|
||||
formatter: () => 'SimpleX Chat',
|
||||
icon: 'simplex',
|
||||
urlType: 'url',
|
||||
},
|
||||
{
|
||||
type: 'nostr',
|
||||
@@ -107,6 +132,7 @@ export const {
|
||||
matcher: /\b(npub1[a-zA-Z0-9]{58})\b/,
|
||||
formatter: () => 'Nostr',
|
||||
icon: 'nostr',
|
||||
urlType: 'url',
|
||||
},
|
||||
{
|
||||
// Website must go last because it's a catch-all
|
||||
@@ -115,6 +141,7 @@ export const {
|
||||
matcher: /^https?:\/\/(?:www\.)?((?:[a-zA-Z0-9-]+\.)+[a-zA-Z]+)/,
|
||||
formatter: ([, value]) => value ?? 'Website',
|
||||
icon: 'ri:global-line',
|
||||
urlType: 'url',
|
||||
},
|
||||
] as const satisfies ContactMethodInfo[]
|
||||
)
|
||||
@@ -135,3 +162,38 @@ export function formatContactMethod(url: string) {
|
||||
|
||||
return { ...getContactMethodInfo('unknown'), formattedValue: url } as const
|
||||
}
|
||||
|
||||
type ContactMethodUrlTypeInfo<T extends string | null | undefined = string> = {
|
||||
value: T
|
||||
labelPlural: string
|
||||
}
|
||||
|
||||
export const {
|
||||
dataArray: contactMethodUrlTypes,
|
||||
dataObject: contactMethodUrlTypesById,
|
||||
getFn: getContactMethodUrlTypeInfo,
|
||||
} = makeHelpersForOptions(
|
||||
'value',
|
||||
(value): ContactMethodUrlTypeInfo<typeof value> => ({
|
||||
value,
|
||||
labelPlural: value ? transformCase(value, 'title') : String(value),
|
||||
}),
|
||||
[
|
||||
{
|
||||
value: 'email',
|
||||
labelPlural: 'emails',
|
||||
},
|
||||
{
|
||||
value: 'telephone',
|
||||
labelPlural: 'phone numbers',
|
||||
},
|
||||
{
|
||||
value: 'url',
|
||||
labelPlural: 'URLs',
|
||||
},
|
||||
] as const satisfies ContactMethodUrlTypeInfo<(typeof contactMethods)[number]['urlType']>[]
|
||||
)
|
||||
|
||||
type _ExpectUrlTypesToHaveAllValues = Assert<
|
||||
Equals<(typeof contactMethods)[number]['urlType'], keyof typeof contactMethodUrlTypesById>
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user