bbcode.ts RawHistoryFolder
1import { z } from 'zod';
2import { RETRO_FONTS } from '$lib/types/text-formatting';
3
4// Build allowed fonts Set from RETRO_FONTS - includes both keys and display names
5const ALLOWED_FONTS_SET = new Set<string>();
6for (const [key, value] of Object.entries(RETRO_FONTS)) {
7 // Add the key (e.g., 'comicsans')
8 ALLOWED_FONTS_SET.add(key.toLowerCase());
9 // Add the display name (e.g., 'comic sans ms')
10 ALLOWED_FONTS_SET.add(value.name.toLowerCase());
11}
12
13// BBCode constraints
14export const BBCODE_CONSTRAINTS = {
15 minFontSize: 8,
16 maxFontSize: 24,
17 namedColors: [
18 'red',
19 'blue',
20 'green',
21 'yellow',
22 'orange',
23 'purple',
24 'pink',
25 'black',
26 'white',
27 'gray',
28 'grey',
29 'brown',
30 'cyan',
31 'magenta',
32 'lime',
33 'navy',
34 'teal',
35 'maroon'
36 ] as const
37};
38
39// Hex color schema - validates 6-digit hex colors
40const hexColorSchema = z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'Invalid hex color format');
41
42// Named color schema - validates against predefined list
43const namedColorSchema = z.enum(BBCODE_CONSTRAINTS.namedColors);
44
45// Combined color schema - accepts either hex or named color
46export const bbcodeColorSchema = z.union([hexColorSchema, namedColorSchema]);
47
48// Font size schema - validates range 8-24
49export const bbcodeFontSizeSchema = z.coerce
50 .number()
51 .int('Font size must be an integer')
52 .min(
53 BBCODE_CONSTRAINTS.minFontSize,
54 `Font size must be at least ${BBCODE_CONSTRAINTS.minFontSize}px`
55 )
56 .max(
57 BBCODE_CONSTRAINTS.maxFontSize,
58 `Font size cannot exceed ${BBCODE_CONSTRAINTS.maxFontSize}px`
59 );
60
61// Font family schema - validates against RETRO_FONTS (both keys and names)
62export const bbcodeFontFamilySchema = z
63 .string()
64 .transform((val) => val.toLowerCase().trim())
65 .refine((val) => ALLOWED_FONTS_SET.has(val), {
66 message: 'Invalid font family'
67 });
68
69// Validation helper functions that return boolean (for use in text-formatter)
70export function isValidBBCodeColor(color: string): boolean {
71 return bbcodeColorSchema.safeParse(color.toLowerCase()).success;
72}
73
74export function isValidBBCodeFontSize(size: string): boolean {
75 return bbcodeFontSizeSchema.safeParse(size).success;
76}
77
78export function isValidBBCodeFont(font: string): boolean {
79 return ALLOWED_FONTS_SET.has(font.toLowerCase().trim());
80}
81
82// Type exports for use elsewhere
83export type BBCodeColor = z.infer<typeof bbcodeColorSchema>;
84export type BBCodeFontSize = z.infer<typeof bbcodeFontSizeSchema>;
85export type BBCodeFontFamily = z.infer<typeof bbcodeFontFamilySchema>;