-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathvalidators.ts
More file actions
60 lines (51 loc) · 1.88 KB
/
validators.ts
File metadata and controls
60 lines (51 loc) · 1.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// src/lib/validators.ts
//
// Pure validation predicates and regex constants.
// No framework dependencies — usable anywhere.
//
// Functions: isValidHex, isValidPort, isIntegerInRange, parseIntClamped, validateImageUrl, safeImageUrl
// Constants: ISO_8601_RE, HEX_64_RE, DATE_RE
import { PORT_MAX, PORT_MIN } from "@/lib/limits"
const STRICT_HEX_RE = /^#[0-9a-fA-F]{6}$/
const PERMISSIVE_HEX_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/
export const ISO_8601_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/
export const HEX_64_RE = /^[0-9a-fA-F]{64}$/
export const DATE_RE = /^\d{4}-\d{2}-\d{2}$/
export function isValidHex(value: string, permissive = false): boolean {
return permissive ? PERMISSIVE_HEX_RE.test(value) : STRICT_HEX_RE.test(value)
}
export function isValidPort(port: number): boolean {
return Number.isInteger(port) && port >= PORT_MIN && port <= PORT_MAX
}
export function isIntegerInRange(value: number, min: number, max: number): boolean {
return Number.isInteger(value) && value >= min && value <= max
}
/** Parse a string to int, clamp to [min, max], fall back to defaultValue for null/NaN. */
export function parseIntClamped(
raw: string | null,
min: number,
max: number,
defaultValue: number
): number {
const parsed = parseInt(raw ?? String(defaultValue), 10)
return Math.min(Math.max(min, Number.isNaN(parsed) ? defaultValue : parsed), max)
}
export function validateImageUrl(url: string): string {
try {
const parsed = new URL(url)
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
throw new Error("Invalid URL protocol")
}
return url
} catch {
throw new Error("Invalid URL in image host response")
}
}
export function safeImageUrl(url: string | undefined): string | undefined {
if (!url) return undefined
try {
return validateImageUrl(url)
} catch {
return undefined
}
}