UNPKG

@restnfeel/agentc-starter-kit

Version:

한국어 기업용 CMS 모듈 - Task Master AI와 함께 빠르게 웹사이트를 구현할 수 있는 재사용 가능한 컴포넌트 시스템

224 lines (201 loc) 5.36 kB
export interface CDNConfig { provider: "cloudflare" | "aws-cloudfront" | "google-cloud-cdn" | "azure-cdn"; endpoint: string; customDomain?: string; accessKey?: string; secretKey?: string; distributionId?: string; zone?: string; enabled: boolean; cacheSettings: { [mimeType: string]: { maxAge: number; // 초 단위 staleWhileRevalidate: number; staleIfError: number; }; }; } export interface CDNProvider { upload(file: Buffer, key: string, mimeType: string): Promise<string>; delete(key: string): Promise<void>; invalidate(keys: string[]): Promise<void>; getUrl(key: string): string; getCacheHeaders(mimeType: string): Record<string, string>; } // 기본 캐시 설정 export const DEFAULT_CACHE_SETTINGS = { // 이미지 "image/jpeg": { maxAge: 31536000, staleWhileRevalidate: 86400, staleIfError: 604800, }, "image/png": { maxAge: 31536000, staleWhileRevalidate: 86400, staleIfError: 604800, }, "image/gif": { maxAge: 31536000, staleWhileRevalidate: 86400, staleIfError: 604800, }, "image/webp": { maxAge: 31536000, staleWhileRevalidate: 86400, staleIfError: 604800, }, "image/avif": { maxAge: 31536000, staleWhileRevalidate: 86400, staleIfError: 604800, }, // 비디오 "video/mp4": { maxAge: 31536000, staleWhileRevalidate: 86400, staleIfError: 604800, }, "video/webm": { maxAge: 31536000, staleWhileRevalidate: 86400, staleIfError: 604800, }, // 오디오 "audio/mp3": { maxAge: 31536000, staleWhileRevalidate: 86400, staleIfError: 604800, }, "audio/wav": { maxAge: 31536000, staleWhileRevalidate: 86400, staleIfError: 604800, }, "audio/ogg": { maxAge: 31536000, staleWhileRevalidate: 86400, staleIfError: 604800, }, // 문서 "application/pdf": { maxAge: 86400, staleWhileRevalidate: 3600, staleIfError: 86400, }, "application/msword": { maxAge: 86400, staleWhileRevalidate: 3600, staleIfError: 86400, }, "text/plain": { maxAge: 86400, staleWhileRevalidate: 3600, staleIfError: 86400, }, // 기본값 default: { maxAge: 3600, staleWhileRevalidate: 300, staleIfError: 3600 }, }; // 환경변수에서 CDN 설정 로드 export function loadCDNConfig(): CDNConfig { return { provider: (process.env.CDN_PROVIDER as CDNConfig["provider"]) || "cloudflare", endpoint: process.env.CDN_ENDPOINT || "", customDomain: process.env.CDN_CUSTOM_DOMAIN, accessKey: process.env.CDN_ACCESS_KEY, secretKey: process.env.CDN_SECRET_KEY, distributionId: process.env.CDN_DISTRIBUTION_ID, zone: process.env.CDN_ZONE, enabled: process.env.CDN_ENABLED === "true", cacheSettings: { ...DEFAULT_CACHE_SETTINGS, // 환경별 오버라이드 가능 }, }; } // 파일 키 생성 (CDN에서 사용할 경로) export function generateCDNKey(fileName: string, uploadId?: string): string { const timestamp = Date.now(); const randomString = Math.random().toString(36).substring(2, 8); if (uploadId) { return `media/${uploadId}/${fileName}`; } return `media/${timestamp}-${randomString}/${fileName}`; } // MIME 타입으로 적절한 캐시 설정 가져오기 export function getCacheSettingsForMimeType(mimeType: string) { return ( DEFAULT_CACHE_SETTINGS[mimeType as keyof typeof DEFAULT_CACHE_SETTINGS] || DEFAULT_CACHE_SETTINGS.default ); } // CDN URL 검증 export function isValidCDNUrl(url: string, config: CDNConfig): boolean { if (!config.enabled) return false; const validDomains = [config.endpoint]; if (config.customDomain) { validDomains.push(config.customDomain); } try { const urlObj = new URL(url); return validDomains.some( (domain) => urlObj.hostname === domain || urlObj.hostname.endsWith(`.${domain}`) ); } catch { return false; } } // CDN 상태 확인 export async function checkCDNHealth(config: CDNConfig): Promise<{ healthy: boolean; latency?: number; error?: string; }> { if (!config.enabled) { return { healthy: false, error: "CDN disabled" }; } const startTime = Date.now(); try { const testUrl = config.customDomain ? `https://${config.customDomain}/health-check` : `${config.endpoint}/health-check`; const response = await fetch(testUrl, { method: "HEAD", signal: AbortSignal.timeout(5000), }); const latency = Date.now() - startTime; return { healthy: response.ok, latency, error: response.ok ? undefined : `HTTP ${response.status}`, }; } catch (error) { return { healthy: false, latency: Date.now() - startTime, error: error instanceof Error ? error.message : "Unknown error", }; } } // CDN 통계 export interface CDNStats { totalRequests: number; cacheHitRate: number; bandwidthUsed: number; // bytes averageLatency: number; // ms errorRate: number; lastUpdated: Date; } // 모의 CDN 통계 (실제 구현에서는 각 프로바이더 API 사용) export function getMockCDNStats(): CDNStats { return { totalRequests: 150000, cacheHitRate: 0.94, bandwidthUsed: 2.5 * 1024 * 1024 * 1024, // 2.5GB averageLatency: 45, errorRate: 0.002, lastUpdated: new Date(), }; }