UNPKG

@restnfeel/agentc-starter-kit

Version:

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

275 lines (239 loc) 7.08 kB
/** * Component Registry System * 서비스 티어별 컴포넌트 관리 시스템 */ import { ComponentRegistry, ComponentDefinition, ComponentType, ServiceTier, BaseComponent, ComponentSettings, ComponentSchema, } from "../../types/template-system"; export class TemplateComponentRegistry implements ComponentRegistry { private components: Map<string, ComponentDefinition> = new Map(); private tierComponents: Map<ServiceTier, Set<ComponentType>> = new Map(); constructor() { this.initializeTierMappings(); } /** * 서비스 티어별 사용 가능한 컴포넌트 초기화 */ private initializeTierMappings(): void { // Starter 티어 - 기본 컴포넌트만 this.tierComponents.set( ServiceTier.STARTER, new Set([ ComponentType.HERO, ComponentType.ABOUT, ComponentType.CONTACT, ComponentType.FOOTER, ]) ); // Standard 티어 - Starter + 추가 컴포넌트 this.tierComponents.set( ServiceTier.STANDARD, new Set([ ComponentType.HERO, ComponentType.ABOUT, ComponentType.SERVICES, ComponentType.TESTIMONIALS, ComponentType.BLOG, ComponentType.CONTACT, ComponentType.FOOTER, ]) ); // Plus 티어 - 모든 컴포넌트 this.tierComponents.set( ServiceTier.PLUS, new Set([ ComponentType.HERO, ComponentType.ABOUT, ComponentType.SERVICES, ComponentType.TESTIMONIALS, ComponentType.BLOG, ComponentType.CONTACT, ComponentType.FOOTER, ComponentType.TEAM, ComponentType.GALLERY, ComponentType.NEWSLETTER, ComponentType.CASE_STUDIES, ]) ); } /** * 컴포넌트 등록 */ register(component: ComponentDefinition): void { const key = this.getComponentKey(component.type, component.tier); this.components.set(key, component); } /** * 특정 티어의 컴포넌트 조회 */ get(type: ComponentType, tier: ServiceTier): ComponentDefinition | null { // 요청된 티어에서 컴포넌트가 사용 가능한지 확인 if (!this.isComponentAvailableInTier(type, tier)) { return null; } // 정확한 티어의 컴포넌트를 먼저 찾기 let key = this.getComponentKey(type, tier); let component = this.components.get(key); if (component) { return component; } // 하위 호환성을 위해 낮은 티어의 컴포넌트 찾기 const tierHierarchy = [ ServiceTier.STARTER, ServiceTier.STANDARD, ServiceTier.PLUS, ]; const currentTierIndex = tierHierarchy.indexOf(tier); for (let i = currentTierIndex - 1; i >= 0; i--) { key = this.getComponentKey(type, tierHierarchy[i]); component = this.components.get(key); if (component) { return component; } } return null; } /** * 특정 티어에서 사용 가능한 모든 컴포넌트 조회 */ getAvailable(tier: ServiceTier): ComponentDefinition[] { const availableTypes = this.tierComponents.get(tier) || new Set(); const components: ComponentDefinition[] = []; availableTypes.forEach((type) => { const component = this.get(type, tier); if (component) { components.push(component); } }); return components.sort((a, b) => a.name.localeCompare(b.name)); } /** * 컴포넌트가 특정 티어에서 유효한지 검증 */ validate(component: BaseComponent, tier: ServiceTier): boolean { // 컴포넌트가 해당 티어에서 사용 가능한지 확인 if (!this.isComponentAvailableInTier(component.type, tier)) { return false; } // 컴포넌트가 등록되어 있는지 확인 const definition = this.get(component.type, tier); if (!definition) { return false; } // 컴포넌트 설정이 스키마에 맞는지 검증 return this.validateComponentSettings( component.settings, definition.schema ); } /** * 컴포넌트가 특정 티어에서 사용 가능한지 확인 */ private isComponentAvailableInTier( type: ComponentType, tier: ServiceTier ): boolean { const availableComponents = this.tierComponents.get(tier); return availableComponents ? availableComponents.has(type) : false; } /** * 컴포넌트 키 생성 */ private getComponentKey(type: ComponentType, tier: ServiceTier): string { return `${type}-${tier}`; } /** * 컴포넌트 설정이 스키마에 맞는지 검증 */ private validateComponentSettings( settings: ComponentSettings, _schema: ComponentSchema ): boolean { // 기본 필수 필드 확인 if ( typeof settings.enabled !== "boolean" || typeof settings.visible !== "boolean" || typeof settings.customizable !== "boolean" ) { return false; } // 추가 스키마 검증 로직은 필요에 따라 구현 return true; } /** * 등록된 모든 컴포넌트 조회 */ getAllComponents(): ComponentDefinition[] { return Array.from(this.components.values()); } /** * 특정 타입의 모든 티어 버전 조회 */ getComponentVariants(type: ComponentType): ComponentDefinition[] { const variants: ComponentDefinition[] = []; [ServiceTier.STARTER, ServiceTier.STANDARD, ServiceTier.PLUS].forEach( (tier) => { const component = this.get(type, tier); if (component) { variants.push(component); } } ); return variants; } /** * 컴포넌트 등록 해제 */ unregister(type: ComponentType, tier: ServiceTier): boolean { const key = this.getComponentKey(type, tier); return this.components.delete(key); } /** * 레지스트리 초기화 */ clear(): void { this.components.clear(); } /** * 티어 업그레이드 시 사용 가능한 새로운 컴포넌트 조회 */ getNewComponentsForTierUpgrade( fromTier: ServiceTier, toTier: ServiceTier ): ComponentType[] { const fromComponents = this.tierComponents.get(fromTier) || new Set(); const toComponents = this.tierComponents.get(toTier) || new Set(); const newComponents: ComponentType[] = []; toComponents.forEach((component) => { if (!fromComponents.has(component)) { newComponents.push(component); } }); return newComponents; } /** * 티어별 컴포넌트 제한 확인 */ getTierRestrictions(tier: ServiceTier): { allowedComponents: ComponentType[]; restrictedComponents: ComponentType[]; } { const allowedComponents = Array.from(this.tierComponents.get(tier) || []); const allComponents = Object.values(ComponentType); const restrictedComponents = allComponents.filter( (comp) => !allowedComponents.includes(comp) ); return { allowedComponents, restrictedComponents, }; } } // 싱글톤 인스턴스 export export const componentRegistry = new TemplateComponentRegistry();