import { computed, type Ref } from 'vue' /** Strip separators; keep digits and letters (suffix may contain letters). */ export function normalizePidSearchValue(value: string): string { return value.replace(/[^0-9a-zA-Z]/g, '') } /** * Check if a string looks like a personnummer (Swedish personal identity number) * @param value - String value to check * @returns Boolean indicating if the value looks like a personnummer */ export function isPidString(value: string): boolean { const normalized = normalizePidSearchValue(value) const digitsOnly = value.replace(/\D/g, '') if (normalized.length < 6 && digitsOnly.length < 6) { return false } const firstSix = digitsOnly.substring(0, 6) if (firstSix.length >= 6) { const year = parseInt(firstSix.substring(0, 4)) const month = parseInt(firstSix.substring(4, 6)) if (year >= 1900 && year <= 2099 && month >= 1 && month <= 12) { return true } } if (/^\d{8}/.test(normalized) && normalized.length >= 8) { return true } if (digitsOnly.length >= 8) { return true } return false } /** Format as yyyymmdd-nnnn; last four may be alphanumeric (e.g. coordination numbers). */ export function formatPidWithDash(value: string): string { if (!isPidString(value)) { return value.replace(/-$/, '') } const normalized = normalizePidSearchValue(value) if (normalized.length <= 8) { return normalized.slice(0, 8) } const datePart = normalized.slice(0, 8) if (!/^\d{8}$/.test(datePart)) { const digits = value.replace(/\D/g, '') if (digits.length > 8) { return `${digits.slice(0, 8)}-${digits.slice(8)}` } return digits } return `${datePart}-${normalized.slice(8, 12)}` } export const PID_MASK = '00000000-XXXX' export const PID_MASK_OPTIONS = { lazy: true, definitions: { X: /[0-9A-Za-z]/, }, } as const /** * Composable for detecting if a string looks like a personnummer (Swedish personal identity number) * @param value - Reactive string value to check (Ref) * @returns Computed boolean indicating if the value looks like a personnummer */ export function useIsPid(value: Ref) { const isPid = computed(() => isPidString(value.value)) return { isPid, } }