lean4-code-actions
Version:
Refactorings and snippets for Lean 4
78 lines (59 loc) • 2.36 kB
text/typescript
import { escape } from 'libs/utils/regexp'
import { getDuplicatesRefinement } from 'libs/utils/zod'
import { z } from 'zod'
import { Protocol, ProtocolSchema } from './Protocol'
export const ContactPathSchema = z.string().min(1).transform(c => c.trim())
export type ContactPath = z.infer<typeof ContactPathSchema>
/**
* Note: z.string().url() is relaxed: it supports mailto: and tel: protocols with arbitrary data after protocol
*/
export const ContactSchema = z.string().url().min(1).describe('Contact')
export const ContactsSchema = z.array(ContactSchema)
.superRefine(getDuplicatesRefinement('Contact', parseContactUid))
export const ContactUidSchema = ContactSchema
export type Contact = z.infer<typeof ContactSchema>
export type ContactUid = z.infer<typeof ContactUidSchema>
export function parseContact(contact: Contact): Contact {
return ContactSchema.parse(contact)
}
export function parseContacts(contacts: Contact[]): Contact[] {
return ContactsSchema.parse(contacts)
}
export function parseContactUid(contactUid: ContactUid): ContactUid {
return ContactUidSchema.parse(contactUid)
}
export const ContactRegex = new RegExp(`^(?:${ProtocolSchema.options.map(escape).join('|')}):`)
export interface Contactable {
contacts: Contact[]
}
export function getContact(contactable: Contactable, protocol: Protocol) {
return contactable.contacts.find(c => c.startsWith(protocol))
}
export function getEmail(contactable: Contactable) {
return getContact(contactable, ProtocolSchema.enum.mailto)?.replace('mailto:', '')
}
export function getContactDisplayValue(contact: Contact) {
const url = new URL(contact)
const protocol = url.protocol.replace(':', '')
switch (protocol) {
case 'http':
case 'https':
case 'ftp':
return contact
default: {
// most contacts have a ${protocol}:${key} format (e.g. mailto:example@example.com, or tel://+123456789)
// for other contacts, just return the full contact
const splinters = contact.split(':')
return splinters[1] ? splinters[1].replace(/^\/\//, '') : contact
}
}
}
export function mailto(email: string) {
return parseContact(`mailto:${email}`)
}
export function tel(telephone: string) {
return parseContact(`tel://${telClean(telephone)}`)
}
export function telClean(phone: string) {
return phone.replace(/[^+\d]/g, '')
}