import { z } from 'zod';
export const FetchRssSchema = z.object({
url: z.string().url('有効なURLを入力してください'),
limit: z.number().int().min(1).max(100).optional().default(10),
includeContent: z.boolean().optional().default(false),
startDate: z.string().optional(),
endDate: z.string().optional()
}).refine((data) => {
if (data.startDate && data.endDate) {
const start = new Date(data.startDate);
const end = new Date(data.endDate);
return start <= end;
}
return true;
}, {
message: '開始日は終了日より前である必要があります'
});
export const AddFeedSchema = z.object({
name: z.string().min(1, 'フィード名は必須です').max(100, 'フィード名は100文字以内で入力してください'),
url: z.string().url('有効なURLを入力してください')
});
export const RemoveFeedSchema = z.object({
feedId: z.string().min(1, 'フィードIDは必須です')
});
export function validateUrl(url: string): boolean {
try {
const parsedUrl = new URL(url);
return ['http:', 'https:'].includes(parsedUrl.protocol);
} catch {
return false;
}
}
export function sanitizeString(input: string): string {
return input
.replace(/[<>]/g, '')
.replace(/javascript:/gi, '')
.trim();
}
export function isValidDate(dateString: string): boolean {
const date = new Date(dateString);
return !isNaN(date.getTime());
}
export function isDateInRange(itemDate: string, startDate?: string, endDate?: string): boolean {
if (!startDate && !endDate) return true;
const itemDateTime = new Date(itemDate).getTime();
if (startDate && new Date(startDate).getTime() > itemDateTime) {
return false;
}
if (endDate && new Date(endDate).getTime() < itemDateTime) {
return false;
}
return true;
}
export type FetchRssParams = z.infer<typeof FetchRssSchema>;
export type AddFeedParams = z.infer<typeof AddFeedSchema>;
export type RemoveFeedParams = z.infer<typeof RemoveFeedSchema>;