@json-to-office/shared 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +18 -0
- package/README.md +9 -0
- package/dist/cache/index.d.ts +464 -0
- package/dist/cache/index.js +738 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/chunk-244MHDOZ.js +39 -0
- package/dist/chunk-244MHDOZ.js.map +1 -0
- package/dist/chunk-5J43F4XD.js +181 -0
- package/dist/chunk-5J43F4XD.js.map +1 -0
- package/dist/chunk-ZKD5BAMU.js +382 -0
- package/dist/chunk-ZKD5BAMU.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/schema-utils-CbCi6dEk.d.ts +43 -0
- package/dist/schemas/schema-utils.d.ts +2 -0
- package/dist/schemas/schema-utils.js +15 -0
- package/dist/schemas/schema-utils.js.map +1 -0
- package/dist/types/warnings.d.ts +9 -0
- package/dist/types/warnings.js +1 -0
- package/dist/types/warnings.js.map +1 -0
- package/dist/utils/semver.d.ts +11 -0
- package/dist/utils/semver.js +13 -0
- package/dist/utils/semver.js.map +1 -0
- package/dist/validation/unified/index.d.ts +66 -0
- package/dist/validation/unified/index.js +41 -0
- package/dist/validation/unified/index.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cache/manager.ts","../../src/cache/memory-cache.ts","../../src/cache/config.ts","../../src/cache/analytics.ts"],"sourcesContent":["/**\n * Cache Manager Base Class\n * Abstract base class for cache implementations\n */\n\nimport { EventEmitter } from 'events';\nimport {\n CachedComponent,\n CacheConfiguration,\n CacheStatistics,\n ComponentStatistics,\n} from './types';\n\n/**\n * Main cache manager abstract class\n */\nexport abstract class ComponentCacheManager extends EventEmitter {\n protected config: CacheConfiguration;\n protected stats: CacheStatistics;\n\n constructor(config: CacheConfiguration) {\n super();\n this.config = config;\n this.stats = this.initializeStats();\n }\n\n /**\n * Get a cached component\n */\n abstract get(key: string): Promise<CachedComponent | undefined>;\n\n /**\n * Set a cached component\n */\n abstract set(key: string, component: CachedComponent): Promise<void>;\n\n /**\n * Check if key exists\n */\n abstract has(key: string): Promise<boolean>;\n\n /**\n * Delete a cached entry\n */\n abstract delete(key: string): Promise<boolean>;\n\n /**\n * Clear all cache entries\n */\n abstract clear(): Promise<void>;\n\n /**\n * Get all keys (for utilities)\n */\n abstract getKeys(): Promise<string[]>;\n\n /**\n * Get cache statistics with deep immutability\n */\n getStats(): CacheStatistics {\n // Create a deep copy of the componentStats Map\n const componentStatsCopy = new Map<string, ComponentStatistics>();\n this.stats.componentStats.forEach((value, key) => {\n // Deep copy each ComponentStatistics object\n componentStatsCopy.set(key, { ...value });\n });\n\n // Return a deep copy of the stats object\n return {\n ...this.stats,\n componentStats: componentStatsCopy,\n };\n }\n\n /**\n * Get configuration with deep immutability\n */\n getConfig(): CacheConfiguration {\n // Deep copy the configuration object\n const configCopy: CacheConfiguration = {\n enabled: this.config.enabled,\n evictionPolicy: this.config.evictionPolicy,\n memory: { ...this.config.memory },\n performance: { ...this.config.performance },\n };\n\n // Deep copy optional disk configuration if present\n if (this.config.disk) {\n configCopy.disk = { ...this.config.disk };\n }\n\n // Deep copy componentConfig if present\n if (this.config.componentConfig) {\n configCopy.componentConfig = {};\n for (const [key, value] of Object.entries(this.config.componentConfig)) {\n configCopy.componentConfig[key] = { ...value };\n }\n }\n\n return configCopy;\n }\n\n /**\n * Get multiple entries (batch operation)\n */\n async getMany(keys: string[]): Promise<Map<string, CachedComponent>> {\n const results = new Map<string, CachedComponent>();\n\n if (this.config.performance.parallelProcessing) {\n const promises = keys.map(async (key) => {\n const value = await this.get(key);\n if (value) results.set(key, value);\n });\n await Promise.all(promises);\n } else {\n for (const key of keys) {\n const value = await this.get(key);\n if (value) results.set(key, value);\n }\n }\n\n return results;\n }\n\n /**\n * Set multiple entries (batch operation)\n */\n async setMany(entries: [string, CachedComponent][]): Promise<void> {\n if (this.config.performance.parallelProcessing) {\n const promises = entries.map(([key, value]) => this.set(key, value));\n await Promise.all(promises);\n } else {\n for (const [key, value] of entries) {\n await this.set(key, value);\n }\n }\n }\n\n /**\n * Delete multiple entries\n */\n async deleteMany(keys: string[]): Promise<number> {\n let deleted = 0;\n\n if (this.config.performance.parallelProcessing) {\n const results = await Promise.all(keys.map((key) => this.delete(key)));\n deleted = results.filter(Boolean).length;\n } else {\n for (const key of keys) {\n if (await this.delete(key)) {\n deleted++;\n }\n }\n }\n\n return deleted;\n }\n\n /**\n * Initialize statistics\n */\n protected initializeStats(): CacheStatistics {\n return {\n entries: 0,\n totalSize: 0,\n hitRate: 0,\n missRate: 0,\n totalHits: 0,\n totalMisses: 0,\n avgResponseTime: 0,\n evictions: 0,\n componentStats: new Map(),\n };\n }\n\n /**\n * Update statistics on cache hit\n */\n protected updateHitStats(key: string, component: CachedComponent): void {\n this.stats.totalHits++;\n this.updateComponentStats(component.componentName, 'hit');\n this.recalculateRates();\n this.emit('hit', key, component);\n }\n\n /**\n * Update statistics on cache miss\n */\n protected updateMissStats(key: string, componentName?: string): void {\n this.stats.totalMisses++;\n if (componentName) {\n this.updateComponentStats(componentName, 'miss');\n }\n this.recalculateRates();\n this.emit('miss', key);\n }\n\n /**\n * Update component-specific statistics\n */\n protected updateComponentStats(componentName: string, event: 'hit' | 'miss'): void {\n if (!this.stats.componentStats.has(componentName)) {\n this.stats.componentStats.set(componentName, {\n name: componentName,\n hits: 0,\n misses: 0,\n avgProcessTime: 0,\n avgSize: 0,\n entries: 0,\n });\n }\n\n const stats = this.stats.componentStats.get(componentName)!;\n if (event === 'hit') {\n stats.hits++;\n } else {\n stats.misses++;\n }\n }\n\n /**\n * Recalculate hit/miss rates\n */\n protected recalculateRates(): void {\n const total = this.stats.totalHits + this.stats.totalMisses;\n if (total > 0) {\n this.stats.hitRate = this.stats.totalHits / total;\n this.stats.missRate = this.stats.totalMisses / total;\n }\n }\n\n /**\n * Emit statistics periodically\n */\n protected emitStats(): void {\n this.emit('stats', this.getStats());\n }\n}\n","/**\n * Memory Cache Implementation\n * In-memory cache with LRU eviction policy\n */\n\nimport { ComponentCacheManager } from './manager';\nimport { CachedComponent, CacheConfiguration } from './types';\n\n/**\n * LRU node for doubly-linked list\n */\nclass LRUNode<T> {\n key: string;\n value: T;\n prev: LRUNode<T> | null = null;\n next: LRUNode<T> | null = null;\n\n constructor(key: string, value: T) {\n this.key = key;\n this.value = value;\n }\n}\n\n/**\n * In-memory cache with LRU eviction\n */\nexport class MemoryCache extends ComponentCacheManager {\n private cache: Map<string, LRUNode<CachedComponent>>;\n private head: LRUNode<CachedComponent> | null = null;\n private tail: LRUNode<CachedComponent> | null = null;\n private currentSize: number = 0;\n private keyToComponentName: Map<string, string> = new Map();\n private cleanupTimer?: NodeJS.Timeout;\n\n constructor(config: CacheConfiguration) {\n super(config);\n this.cache = new Map();\n if (config.memory.cleanupInterval > 0) {\n this.startCleanupTimer();\n }\n }\n\n async get(key: string): Promise<CachedComponent | undefined> {\n const node = this.cache.get(key);\n\n if (!node) {\n // Try to get component name from our mapping first, then from the key itself\n const componentName =\n this.keyToComponentName.get(key) || this.extractComponentNameFromKey(key);\n this.updateMissStats(key, componentName);\n return undefined;\n }\n\n const component = node.value;\n\n // Check if expired\n if (this.isExpired(component)) {\n await this.delete(key);\n this.updateMissStats(key, component.componentName);\n return undefined;\n }\n\n // Update access time and move to head (MRU)\n component.lastAccessed = Date.now();\n component.hits++;\n this.moveToHead(node);\n\n this.updateHitStats(key, component);\n return component;\n }\n\n async set(key: string, component: CachedComponent): Promise<void> {\n // Check if component is cacheable\n if (!this.isCacheable(component.componentName)) {\n return;\n }\n\n // Store the component name mapping\n this.keyToComponentName.set(key, component.componentName);\n\n // Remove existing entry if present\n if (this.cache.has(key)) {\n await this.delete(key);\n }\n\n // Check size constraints\n await this.ensureSpace(component.size);\n\n // Create new node and add to head\n const node = new LRUNode(key, component);\n this.cache.set(key, node);\n this.addToHead(node);\n\n // Update stats\n this.currentSize += component.size;\n this.stats.entries++;\n this.stats.totalSize = this.currentSize;\n\n // Update component stats\n let componentStats = this.stats.componentStats.get(component.componentName);\n if (!componentStats) {\n componentStats = {\n name: component.componentName,\n hits: 0,\n misses: 0,\n entries: 0,\n avgSize: 0,\n avgProcessTime: 0,\n };\n this.stats.componentStats.set(component.componentName, componentStats);\n }\n componentStats.entries++;\n componentStats.avgSize =\n (componentStats.avgSize * (componentStats.entries - 1) + component.size) /\n componentStats.entries;\n\n this.emit('set', key, component);\n }\n\n async has(key: string): Promise<boolean> {\n const node = this.cache.get(key);\n if (!node) return false;\n return !this.isExpired(node.value);\n }\n\n async delete(key: string): Promise<boolean> {\n const node = this.cache.get(key);\n if (!node) return false;\n\n this.removeNode(node);\n this.cache.delete(key);\n this.keyToComponentName.delete(key);\n\n // Update stats\n this.currentSize -= node.value.size;\n this.stats.entries--;\n this.stats.totalSize = this.currentSize;\n\n // Update component stats\n const componentStats = this.stats.componentStats.get(node.value.componentName);\n if (componentStats && componentStats.entries > 0) {\n componentStats.entries--;\n }\n\n return true;\n }\n\n async clear(): Promise<void> {\n this.cache.clear();\n this.keyToComponentName.clear();\n this.head = null;\n this.tail = null;\n this.currentSize = 0;\n this.stats = this.initializeStats();\n }\n\n async getKeys(): Promise<string[]> {\n return Array.from(this.cache.keys());\n }\n\n /**\n * Extract component name from cache key\n */\n private extractComponentNameFromKey(key: string): string | undefined {\n // Cache key format: version:componentName:propsHash:...\n const parts = key.split(':');\n return parts.length >= 2 ? parts[1] : undefined;\n }\n\n /**\n * Check if component is expired\n */\n private isExpired(component: CachedComponent): boolean {\n if (!component.ttl) return false;\n return Date.now() - component.timestamp > component.ttl * 1000;\n }\n\n /**\n * Check if component is cacheable\n */\n private isCacheable(componentName: string): boolean {\n const componentConfig = this.config.componentConfig?.[componentName];\n return componentConfig?.cacheable !== false;\n }\n\n /**\n * Ensure enough space for new entry\n */\n private async ensureSpace(requiredSize: number): Promise<void> {\n const maxSize = this.config.memory.maxSize * 1024 * 1024; // Convert MB to bytes\n\n // Evict based on size\n while (this.currentSize + requiredSize > maxSize && this.tail) {\n const keyToEvict = this.tail.key;\n await this.delete(keyToEvict);\n this.stats.evictions++;\n this.emit('evict', keyToEvict, 'size');\n }\n\n // Also check max entries\n const maxEntries = this.config.memory.maxEntries;\n while (this.stats.entries >= maxEntries && this.tail) {\n const keyToEvict = this.tail.key;\n await this.delete(keyToEvict);\n this.stats.evictions++;\n this.emit('evict', keyToEvict, 'size');\n }\n }\n\n /**\n * LRU operations - Add node to head\n */\n private addToHead(node: LRUNode<CachedComponent>): void {\n node.prev = null;\n node.next = this.head;\n\n if (this.head) {\n this.head.prev = node;\n }\n\n this.head = node;\n\n if (!this.tail) {\n this.tail = node;\n }\n }\n\n /**\n * Remove node from list\n */\n private removeNode(node: LRUNode<CachedComponent>): void {\n if (node.prev) {\n node.prev.next = node.next;\n } else {\n this.head = node.next;\n }\n\n if (node.next) {\n node.next.prev = node.prev;\n } else {\n this.tail = node.prev;\n }\n }\n\n /**\n * Move node to head\n */\n private moveToHead(node: LRUNode<CachedComponent>): void {\n if (node === this.head) return;\n this.removeNode(node);\n this.addToHead(node);\n }\n\n /**\n * Start cleanup timer for expired entries\n */\n private startCleanupTimer(): void {\n this.cleanupTimer = setInterval(\n async () => {\n const keysToDelete: string[] = [];\n\n for (const [key, node] of this.cache) {\n if (this.isExpired(node.value)) {\n keysToDelete.push(key);\n }\n }\n\n for (const key of keysToDelete) {\n await this.delete(key);\n this.stats.evictions++;\n this.emit('evict', key, 'ttl');\n }\n },\n (this.config.memory?.cleanupInterval || 300) * 1000\n );\n }\n\n /**\n * Stop cleanup timer\n */\n destroy(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n }\n }\n}\n","/**\n * Cache Configuration\n * Default configuration and environment-based configuration\n */\n\nimport { CacheConfiguration } from './types';\n\n/**\n * Default cache configuration\n */\nexport const DEFAULT_CACHE_CONFIG: CacheConfiguration = {\n enabled: true,\n memory: {\n enabled: true,\n maxSize: 100, // 100MB\n maxEntries: 1000,\n defaultTTL: 3600, // 1 hour\n cleanupInterval: 300, // 5 minutes\n },\n evictionPolicy: 'lru',\n componentConfig: {\n // Static content - longer TTL\n text: { cacheable: true, ttl: 7200 }, // 2 hours\n heading: { cacheable: true, ttl: 7200 },\n columns: { cacheable: true, ttl: 3600 }, // 1 hour\n section: { cacheable: true, ttl: 3600 },\n\n // Dynamic content - shorter TTL\n 'custom-data': { cacheable: true, ttl: 300 }, // 5 minutes\n 'api-content': { cacheable: true, ttl: 180 }, // 3 minutes\n\n // Resource-intensive components - medium TTL\n image: { cacheable: true, ttl: 1800 }, // 30 minutes\n table: { cacheable: true, ttl: 1800 },\n },\n performance: {\n trackMetrics: true,\n metricsSampleRate: 1.0,\n enableWarming: false,\n parallelProcessing: true,\n },\n};\n\n/**\n * Get cache configuration from environment variables\n */\nexport function getCacheConfigFromEnv(): Partial<CacheConfiguration> {\n const config: Partial<CacheConfiguration> = {};\n\n // Global enabled flag\n if (process.env.CACHE_ENABLED !== undefined) {\n config.enabled = process.env.CACHE_ENABLED !== 'false';\n }\n\n // Memory cache configuration\n if (\n process.env.CACHE_MAX_SIZE ||\n process.env.CACHE_MAX_ENTRIES ||\n process.env.CACHE_TTL\n ) {\n config.memory = {\n enabled: true,\n maxSize: parseInt(process.env.CACHE_MAX_SIZE || '100'),\n maxEntries: parseInt(process.env.CACHE_MAX_ENTRIES || '1000'),\n defaultTTL: parseInt(process.env.CACHE_TTL || '3600'),\n cleanupInterval: parseInt(process.env.CACHE_CLEANUP_INTERVAL || '300'),\n };\n }\n\n // Performance configuration\n if (\n process.env.CACHE_TRACK_METRICS !== undefined ||\n process.env.CACHE_WARMING !== undefined\n ) {\n config.performance = {\n trackMetrics: process.env.CACHE_TRACK_METRICS !== 'false',\n metricsSampleRate: parseFloat(process.env.CACHE_SAMPLE_RATE || '1.0'),\n enableWarming: process.env.CACHE_WARMING === 'true',\n parallelProcessing: process.env.CACHE_PARALLEL !== 'false',\n };\n }\n\n return config;\n}\n\n/**\n * Merge configurations with priority\n */\nexport function mergeConfigs(\n ...configs: Partial<CacheConfiguration>[]\n): CacheConfiguration {\n const merged = { ...DEFAULT_CACHE_CONFIG };\n\n for (const config of configs) {\n if (config.enabled !== undefined) {\n merged.enabled = config.enabled;\n }\n\n if (config.memory) {\n merged.memory = { ...merged.memory, ...config.memory };\n }\n\n if (config.disk) {\n merged.disk = { ...merged.disk, ...config.disk };\n }\n\n if (config.evictionPolicy) {\n merged.evictionPolicy = config.evictionPolicy;\n }\n\n if (config.componentConfig) {\n merged.componentConfig = { ...merged.componentConfig, ...config.componentConfig };\n }\n\n if (config.performance) {\n merged.performance = { ...merged.performance, ...config.performance };\n }\n }\n\n return merged;\n}\n","/**\n * Component Cache Analytics\n * Advanced analytics and insights for component-level caching\n */\n\nimport { CacheStatistics } from './types';\n\n/**\n * Time-series data point for tracking metrics over time\n */\nexport interface TimeSeriesPoint {\n timestamp: number;\n value: number;\n}\n\n/**\n * Component performance metrics\n */\nexport interface ComponentPerformanceMetrics {\n /** Component name identifier */\n componentName: string;\n /** Cache hit rate (0-1) */\n hitRate: number;\n /** Total requests (hits + misses) */\n totalRequests: number;\n /** Average response time for cache hits (ms) */\n avgHitTime: number;\n /** Average response time for cache misses (ms) */\n avgMissTime: number;\n /** Cache efficiency score (0-100) */\n efficiencyScore: number;\n /** Memory usage in bytes */\n memoryUsage: number;\n /** Time saved by caching (ms) */\n timeSaved: number;\n /** Cost-benefit ratio */\n costBenefitRatio: number;\n}\n\n/**\n * Component cache trends over time\n */\nexport interface ComponentCacheTrends {\n /** Component name */\n componentName: string;\n /** Hit rate trend */\n hitRateTrend: TimeSeriesPoint[];\n /** Request volume trend */\n requestVolumeTrend: TimeSeriesPoint[];\n /** Response time trend */\n responseTimeTrend: TimeSeriesPoint[];\n /** Memory usage trend */\n memoryUsageTrend: TimeSeriesPoint[];\n}\n\n/**\n * Cache optimization recommendations\n */\nexport interface CacheOptimizationRecommendation {\n /** Component name to optimize */\n componentName: string;\n /** Recommendation type */\n type:\n | 'increase_ttl'\n | 'decrease_ttl'\n | 'increase_size'\n | 'disable_cache'\n | 'enable_cache';\n /** Recommendation description */\n description: string;\n /** Expected improvement percentage */\n expectedImprovement: number;\n /** Priority level (1-5, 5 being highest) */\n priority: number;\n /** Detailed reasoning */\n reasoning: string;\n}\n\n/**\n * Comprehensive cache analytics report\n */\nexport interface CacheAnalyticsReport {\n /** Report generation timestamp */\n timestamp: number;\n /** Overall cache health score (0-100) */\n healthScore: number;\n /** Total cache efficiency percentage */\n overallEfficiency: number;\n /** Per-component performance metrics */\n componentMetrics: ComponentPerformanceMetrics[];\n /** Component cache trends */\n trends: ComponentCacheTrends[];\n /** Optimization recommendations */\n recommendations: CacheOptimizationRecommendation[];\n /** Top performing components */\n topPerformers: string[];\n /** Components needing attention */\n needsAttention: string[];\n /** Estimated performance gain from caching */\n performanceGain: {\n timeReduction: number; // milliseconds\n cpuReduction: number; // percentage\n memoryOptimization: number; // percentage\n };\n}\n\n/**\n * Component Cache Analytics Engine\n */\nexport class ComponentCacheAnalytics {\n private historyWindow: number = 3600000; // 1 hour in milliseconds\n private metricsHistory: Map<string, TimeSeriesPoint[]> = new Map();\n private performanceBaseline: Map<string, number> = new Map();\n\n /**\n * Analyze cache statistics and generate comprehensive report\n */\n analyzeCache(stats: CacheStatistics): CacheAnalyticsReport {\n const componentMetrics = this.calculateComponentMetrics(stats);\n const trends = this.calculateTrends(stats);\n const recommendations = this.generateRecommendations(componentMetrics, trends);\n const healthScore = this.calculateHealthScore(componentMetrics);\n const overallEfficiency = this.calculateOverallEfficiency(componentMetrics);\n const performanceGain = this.calculatePerformanceGain(componentMetrics);\n\n // Identify top performers and components needing attention\n const sortedByEfficiency = [...componentMetrics].sort(\n (a, b) => b.efficiencyScore - a.efficiencyScore\n );\n const topPerformers = sortedByEfficiency\n .slice(0, 3)\n .map((m) => m.componentName);\n const needsAttention = sortedByEfficiency\n .filter((m) => m.efficiencyScore < 50)\n .map((m) => m.componentName);\n\n return {\n timestamp: Date.now(),\n healthScore,\n overallEfficiency,\n componentMetrics,\n trends,\n recommendations,\n topPerformers,\n needsAttention,\n performanceGain,\n };\n }\n\n /**\n * Calculate detailed metrics for each component\n */\n private calculateComponentMetrics(\n stats: CacheStatistics\n ): ComponentPerformanceMetrics[] {\n const metrics: ComponentPerformanceMetrics[] = [];\n\n stats.componentStats.forEach((componentStats, componentName) => {\n const totalRequests = componentStats.hits + componentStats.misses;\n const hitRate = totalRequests > 0 ? componentStats.hits / totalRequests : 0;\n\n // Calculate efficiency score based on multiple factors\n const efficiencyScore = this.calculateEfficiencyScore(\n hitRate,\n componentStats.avgProcessTime,\n componentStats.avgSize,\n componentStats.entries\n );\n\n // Estimate time saved by caching\n const timeSaved = componentStats.hits * componentStats.avgProcessTime;\n\n // Calculate cost-benefit ratio\n const memoryCost = componentStats.entries * componentStats.avgSize;\n const timeBenefit = timeSaved;\n const costBenefitRatio = memoryCost > 0 ? timeBenefit / memoryCost : 0;\n\n metrics.push({\n componentName,\n hitRate,\n totalRequests,\n avgHitTime: 1, // Cache hits are typically ~1ms\n avgMissTime: componentStats.avgProcessTime,\n efficiencyScore,\n memoryUsage: componentStats.entries * componentStats.avgSize,\n timeSaved,\n costBenefitRatio,\n });\n });\n\n return metrics;\n }\n\n /**\n * Calculate efficiency score for a component\n */\n private calculateEfficiencyScore(\n hitRate: number,\n avgProcessTime: number,\n avgSize: number,\n entries: number\n ): number {\n // Weighted scoring system\n const hitRateWeight = 0.4;\n const processingTimeWeight = 0.3;\n const memorySizeWeight = 0.2;\n const utilizationWeight = 0.1;\n\n // Normalize metrics to 0-100 scale\n const hitRateScore = hitRate * 100;\n const processingTimeScore = Math.min(100, (avgProcessTime / 10) * 100); // Assumes 10ms is slow\n const memorySizeScore = Math.max(0, 100 - (avgSize / 10000) * 100); // Assumes 10KB is large\n const utilizationScore = Math.min(100, (entries / 100) * 100); // Assumes 100 entries is good utilization\n\n const score =\n hitRateScore * hitRateWeight +\n processingTimeScore * processingTimeWeight +\n memorySizeScore * memorySizeWeight +\n utilizationScore * utilizationWeight;\n\n return Math.round(score);\n }\n\n /**\n * Calculate trends over time\n */\n private calculateTrends(stats: CacheStatistics): ComponentCacheTrends[] {\n const trends: ComponentCacheTrends[] = [];\n const now = Date.now();\n\n stats.componentStats.forEach((componentStats, componentName) => {\n // Get or create history for this component\n const historyKey = `${componentName}_hitRate`;\n if (!this.metricsHistory.has(historyKey)) {\n this.metricsHistory.set(historyKey, []);\n }\n\n const history = this.metricsHistory.get(historyKey)!;\n const totalRequests = componentStats.hits + componentStats.misses;\n const hitRate = totalRequests > 0 ? componentStats.hits / totalRequests : 0;\n\n // Add current data point\n history.push({ timestamp: now, value: hitRate });\n\n // Clean old data points\n const cutoff = now - this.historyWindow;\n const cleanedHistory = history.filter(\n (point) => point.timestamp > cutoff\n );\n this.metricsHistory.set(historyKey, cleanedHistory);\n\n // Create trend data\n trends.push({\n componentName,\n hitRateTrend: [...cleanedHistory],\n requestVolumeTrend: this.getOrCreateHistory(\n `${componentName}_volume`,\n totalRequests\n ),\n responseTimeTrend: this.getOrCreateHistory(\n `${componentName}_response`,\n componentStats.avgProcessTime\n ),\n memoryUsageTrend: this.getOrCreateHistory(\n `${componentName}_memory`,\n componentStats.entries * componentStats.avgSize\n ),\n });\n });\n\n return trends;\n }\n\n /**\n * Get or create history for a metric\n */\n private getOrCreateHistory(\n key: string,\n currentValue: number\n ): TimeSeriesPoint[] {\n const now = Date.now();\n\n if (!this.metricsHistory.has(key)) {\n this.metricsHistory.set(key, []);\n }\n\n const history = this.metricsHistory.get(key)!;\n history.push({ timestamp: now, value: currentValue });\n\n // Clean old data points\n const cutoff = now - this.historyWindow;\n const cleanedHistory = history.filter((point) => point.timestamp > cutoff);\n this.metricsHistory.set(key, cleanedHistory);\n\n return [...cleanedHistory];\n }\n\n /**\n * Generate optimization recommendations\n */\n private generateRecommendations(\n metrics: ComponentPerformanceMetrics[],\n trends: ComponentCacheTrends[]\n ): CacheOptimizationRecommendation[] {\n const recommendations: CacheOptimizationRecommendation[] = [];\n\n metrics.forEach((metric) => {\n const trend = trends.find((t) => t.componentName === metric.componentName);\n\n // Low hit rate recommendation\n if (metric.hitRate < 0.3 && metric.totalRequests > 10) {\n recommendations.push({\n componentName: metric.componentName,\n type: 'increase_ttl',\n description: `Increase TTL for ${metric.componentName} components to improve hit rate`,\n expectedImprovement: 20,\n priority: 4,\n reasoning: `Current hit rate of ${(metric.hitRate * 100).toFixed(1)}% is below optimal threshold. Increasing TTL could improve cache effectiveness.`,\n });\n }\n\n // High memory usage with low hit rate\n if (metric.memoryUsage > 1000000 && metric.hitRate < 0.5) {\n recommendations.push({\n componentName: metric.componentName,\n type: 'decrease_ttl',\n description: `Reduce cache size for ${metric.componentName} components`,\n expectedImprovement: 15,\n priority: 3,\n reasoning: `High memory usage (${(metric.memoryUsage / 1024 / 1024).toFixed(2)}MB) with moderate hit rate suggests over-caching.`,\n });\n }\n\n // Very low efficiency score\n if (metric.efficiencyScore < 30) {\n recommendations.push({\n componentName: metric.componentName,\n type: 'disable_cache',\n description: `Consider disabling cache for ${metric.componentName} components`,\n expectedImprovement: 10,\n priority: 2,\n reasoning: `Efficiency score of ${metric.efficiencyScore} indicates caching may not be beneficial for this component.`,\n });\n }\n\n // Check trends for declining performance\n if (trend && this.isDecliningSlopbankTrend(trend.hitRateTrend)) {\n recommendations.push({\n componentName: metric.componentName,\n type: 'increase_size',\n description: `Increase cache capacity for ${metric.componentName} components`,\n expectedImprovement: 25,\n priority: 5,\n reasoning: 'Hit rate is declining over time, suggesting cache capacity may be insufficient.',\n });\n }\n });\n\n // Sort by priority\n return recommendations.sort((a, b) => b.priority - a.priority);\n }\n\n /**\n * Check if a trend is declining\n */\n private isDecliningSlopbankTrend(trend: TimeSeriesPoint[]): boolean {\n if (trend.length < 3) return false;\n\n // Simple linear regression to detect trend\n const n = trend.length;\n const recent = trend.slice(-Math.min(10, n)); // Look at last 10 points\n\n if (recent.length < 3) return false;\n\n const firstValue = recent[0].value;\n const lastValue = recent[recent.length - 1].value;\n\n // Declining if dropped by more than 10%\n return (firstValue - lastValue) / firstValue > 0.1;\n }\n\n /**\n * Calculate overall cache health score\n */\n private calculateHealthScore(metrics: ComponentPerformanceMetrics[]): number {\n if (metrics.length === 0) return 0;\n\n const avgEfficiency =\n metrics.reduce((sum, m) => sum + m.efficiencyScore, 0) / metrics.length;\n const avgHitRate =\n metrics.reduce((sum, m) => sum + m.hitRate, 0) / metrics.length;\n\n // Weight efficiency and hit rate\n const healthScore = avgEfficiency * 0.6 + avgHitRate * 100 * 0.4;\n\n return Math.round(healthScore);\n }\n\n /**\n * Calculate overall cache efficiency\n */\n private calculateOverallEfficiency(\n metrics: ComponentPerformanceMetrics[]\n ): number {\n if (metrics.length === 0) return 0;\n\n const totalTimeSaved = metrics.reduce((sum, m) => sum + m.timeSaved, 0);\n const totalMemoryUsed = metrics.reduce((sum, m) => sum + m.memoryUsage, 0);\n const totalRequests = metrics.reduce((sum, m) => sum + m.totalRequests, 0);\n const totalHits = metrics.reduce(\n (sum, m) => sum + m.hitRate * m.totalRequests,\n 0\n );\n\n if (totalRequests === 0) return 0;\n\n // Calculate efficiency as a combination of hit rate and resource utilization\n const hitRateEfficiency = (totalHits / totalRequests) * 100;\n const resourceEfficiency =\n totalMemoryUsed > 0\n ? Math.min(100, (totalTimeSaved / totalMemoryUsed) * 1000)\n : 0;\n\n return Math.round(hitRateEfficiency * 0.7 + resourceEfficiency * 0.3);\n }\n\n /**\n * Calculate performance gain from caching\n */\n private calculatePerformanceGain(metrics: ComponentPerformanceMetrics[]): {\n timeReduction: number;\n cpuReduction: number;\n memoryOptimization: number;\n } {\n const totalTimeSaved = metrics.reduce((sum, m) => sum + m.timeSaved, 0);\n const totalProcessingTime = metrics.reduce(\n (sum, m) => sum + m.totalRequests * m.avgMissTime,\n 0\n );\n // Estimate CPU reduction based on cache hits avoiding processing\n const cpuReduction =\n totalProcessingTime > 0\n ? Math.round((totalTimeSaved / totalProcessingTime) * 100)\n : 0;\n\n // Memory optimization is based on deduplication\n const uniqueEntries = metrics.reduce(\n (sum, m) => sum + m.memoryUsage / m.avgHitTime,\n 0\n );\n const totalDataProcessed = metrics.reduce(\n (sum, m) => sum + m.totalRequests * m.memoryUsage,\n 0\n );\n const memoryOptimization =\n totalDataProcessed > 0\n ? Math.round(\n ((totalDataProcessed - uniqueEntries) / totalDataProcessed) * 100\n )\n : 0;\n\n return {\n timeReduction: Math.round(totalTimeSaved),\n cpuReduction: Math.min(100, cpuReduction),\n memoryOptimization: Math.min(100, memoryOptimization),\n };\n }\n\n /**\n * Reset analytics history\n */\n reset(): void {\n this.metricsHistory.clear();\n this.performanceBaseline.clear();\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// src/utils/semver.ts
|
|
2
|
+
var SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)$/;
|
|
3
|
+
function isValidSemver(version) {
|
|
4
|
+
return SEMVER_RE.test(version);
|
|
5
|
+
}
|
|
6
|
+
function parseSemver(version) {
|
|
7
|
+
const match = version.match(SEMVER_RE);
|
|
8
|
+
if (!match) {
|
|
9
|
+
throw new Error(
|
|
10
|
+
`Invalid semver: "${version}". Expected format: major.minor.patch`
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
major: Number(match[1]),
|
|
15
|
+
minor: Number(match[2]),
|
|
16
|
+
patch: Number(match[3])
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function compareSemver(a, b) {
|
|
20
|
+
const pa = parseSemver(a);
|
|
21
|
+
const pb = parseSemver(b);
|
|
22
|
+
return pa.major - pb.major || pa.minor - pb.minor || pa.patch - pb.patch;
|
|
23
|
+
}
|
|
24
|
+
function latestVersion(versions) {
|
|
25
|
+
if (versions.length === 0) {
|
|
26
|
+
throw new Error("Cannot determine latest version from empty array");
|
|
27
|
+
}
|
|
28
|
+
return versions.reduce(
|
|
29
|
+
(latest, v) => compareSemver(v, latest) > 0 ? v : latest
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export {
|
|
34
|
+
isValidSemver,
|
|
35
|
+
parseSemver,
|
|
36
|
+
compareSemver,
|
|
37
|
+
latestVersion
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=chunk-244MHDOZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/semver.ts"],"sourcesContent":["export interface ParsedSemver {\n major: number;\n minor: number;\n patch: number;\n}\n\nconst SEMVER_RE = /^(\\d+)\\.(\\d+)\\.(\\d+)$/;\n\nexport function isValidSemver(version: string): boolean {\n return SEMVER_RE.test(version);\n}\n\nexport function parseSemver(version: string): ParsedSemver {\n const match = version.match(SEMVER_RE);\n if (!match) {\n throw new Error(\n `Invalid semver: \"${version}\". Expected format: major.minor.patch`\n );\n }\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n };\n}\n\nexport function compareSemver(a: string, b: string): number {\n const pa = parseSemver(a);\n const pb = parseSemver(b);\n return pa.major - pb.major || pa.minor - pb.minor || pa.patch - pb.patch;\n}\n\nexport function latestVersion(versions: string[]): string {\n if (versions.length === 0) {\n throw new Error('Cannot determine latest version from empty array');\n }\n return versions.reduce((latest, v) =>\n compareSemver(v, latest) > 0 ? v : latest\n );\n}\n"],"mappings":";AAMA,IAAM,YAAY;AAEX,SAAS,cAAc,SAA0B;AACtD,SAAO,UAAU,KAAK,OAAO;AAC/B;AAEO,SAAS,YAAY,SAA+B;AACzD,QAAM,QAAQ,QAAQ,MAAM,SAAS;AACrC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR,oBAAoB,OAAO;AAAA,IAC7B;AAAA,EACF;AACA,SAAO;AAAA,IACL,OAAO,OAAO,MAAM,CAAC,CAAC;AAAA,IACtB,OAAO,OAAO,MAAM,CAAC,CAAC;AAAA,IACtB,OAAO,OAAO,MAAM,CAAC,CAAC;AAAA,EACxB;AACF;AAEO,SAAS,cAAc,GAAW,GAAmB;AAC1D,QAAM,KAAK,YAAY,CAAC;AACxB,QAAM,KAAK,YAAY,CAAC;AACxB,SAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG;AACrE;AAEO,SAAS,cAAc,UAA4B;AACxD,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AACA,SAAO,SAAS;AAAA,IAAO,CAAC,QAAQ,MAC9B,cAAc,GAAG,MAAM,IAAI,IAAI,IAAI;AAAA,EACrC;AACF;","names":[]}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// src/schemas/schema-utils.ts
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
function replaceRefs(obj, target, replacement) {
|
|
4
|
+
if (typeof obj !== "object" || obj === null) return;
|
|
5
|
+
if (Array.isArray(obj)) {
|
|
6
|
+
obj.forEach((item) => {
|
|
7
|
+
if (typeof item === "object" && item !== null) {
|
|
8
|
+
replaceRefs(item, target, replacement);
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (obj.$ref === target) {
|
|
14
|
+
obj.$ref = replacement;
|
|
15
|
+
}
|
|
16
|
+
for (const value of Object.values(obj)) {
|
|
17
|
+
if (typeof value === "object" && value !== null) {
|
|
18
|
+
replaceRefs(value, target, replacement);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function fixSchemaReferences(schema, rootDefinitionName = "ComponentDefinition") {
|
|
23
|
+
function traverse(obj, path = "") {
|
|
24
|
+
if (typeof obj !== "object" || obj === null) return;
|
|
25
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
26
|
+
const currentPath = path ? `${path}.${key}` : key;
|
|
27
|
+
if (value && typeof value === "object") {
|
|
28
|
+
const schemaValue = value;
|
|
29
|
+
if (schemaValue.type === "array" && schemaValue.items && Object.keys(schemaValue.items).length === 0) {
|
|
30
|
+
schemaValue.items = {
|
|
31
|
+
$ref: `#/definitions/${rootDefinitionName}`
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (schemaValue.type === "array" && schemaValue.items && typeof schemaValue.items === "object" && "$ref" in schemaValue.items && typeof schemaValue.items.$ref === "string" && /^T\d+$/.test(schemaValue.items.$ref)) {
|
|
35
|
+
schemaValue.items = {
|
|
36
|
+
$ref: `#/definitions/${rootDefinitionName}`
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (typeof schemaValue.$ref === "string" && (/^T\d+$/.test(schemaValue.$ref) || schemaValue.$ref === rootDefinitionName)) {
|
|
40
|
+
schemaValue.$ref = `#/definitions/${rootDefinitionName}`;
|
|
41
|
+
}
|
|
42
|
+
if (key === "$id" && typeof value === "string" && (/^T\d+$/.test(value) || value === rootDefinitionName) && currentPath !== `definitions.${rootDefinitionName}.$id`) {
|
|
43
|
+
delete obj[key];
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
traverse(value, currentPath);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
traverse(schema);
|
|
51
|
+
}
|
|
52
|
+
function convertToJsonSchema(schema, options = {}) {
|
|
53
|
+
const {
|
|
54
|
+
$schema = "https://json-schema.org/draft-07/schema#",
|
|
55
|
+
$id,
|
|
56
|
+
title,
|
|
57
|
+
description,
|
|
58
|
+
definitions = {}
|
|
59
|
+
} = options;
|
|
60
|
+
const schemaJson = JSON.parse(JSON.stringify(schema));
|
|
61
|
+
if (schemaJson.$id && typeof schemaJson.$id === "string" && /^T\d+$/.test(schemaJson.$id)) {
|
|
62
|
+
const recursiveId = schemaJson.$id;
|
|
63
|
+
delete schemaJson.$id;
|
|
64
|
+
replaceRefs(schemaJson, recursiveId, "#");
|
|
65
|
+
}
|
|
66
|
+
const extractedDefinitions = { ...definitions };
|
|
67
|
+
function extractRecursiveSchemas(obj, path = "") {
|
|
68
|
+
if (typeof obj !== "object" || obj === null) return;
|
|
69
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
70
|
+
if (value && typeof value === "object") {
|
|
71
|
+
const schemaValue = value;
|
|
72
|
+
if (schemaValue.$id && typeof schemaValue.$id === "string") {
|
|
73
|
+
const definitionName = schemaValue.$id;
|
|
74
|
+
if (path !== `definitions.${definitionName}`) {
|
|
75
|
+
const { $id: _id, ...schemaWithoutId } = schemaValue;
|
|
76
|
+
extractedDefinitions[definitionName] = schemaWithoutId;
|
|
77
|
+
obj[key] = { $ref: `#/definitions/${definitionName}` };
|
|
78
|
+
extractRecursiveSchemas(
|
|
79
|
+
schemaWithoutId,
|
|
80
|
+
`definitions.${definitionName}`
|
|
81
|
+
);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
extractRecursiveSchemas(
|
|
86
|
+
value,
|
|
87
|
+
path ? `${path}.${key}` : key
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
extractRecursiveSchemas(schemaJson);
|
|
93
|
+
const jsonSchema = { $schema };
|
|
94
|
+
if ($id) jsonSchema.$id = $id;
|
|
95
|
+
Object.assign(jsonSchema, schemaJson);
|
|
96
|
+
jsonSchema.$schema = $schema;
|
|
97
|
+
if ($id) jsonSchema.$id = $id;
|
|
98
|
+
if (title !== void 0) jsonSchema.title = title;
|
|
99
|
+
if (description !== void 0) jsonSchema.description = description;
|
|
100
|
+
if (Object.keys(extractedDefinitions).length > 0) {
|
|
101
|
+
jsonSchema.definitions = extractedDefinitions;
|
|
102
|
+
}
|
|
103
|
+
fixSchemaReferences(jsonSchema);
|
|
104
|
+
return jsonSchema;
|
|
105
|
+
}
|
|
106
|
+
function createComponentSchema(name, config, containerNames, componentDefinitionSchema) {
|
|
107
|
+
const componentStructure = {
|
|
108
|
+
$schema: "https://json-schema.org/draft-07/schema#",
|
|
109
|
+
$id: `${name}.schema.json`,
|
|
110
|
+
title: config.title,
|
|
111
|
+
description: config.description,
|
|
112
|
+
type: "object",
|
|
113
|
+
required: ["name", "props"],
|
|
114
|
+
properties: {
|
|
115
|
+
name: {
|
|
116
|
+
type: "string",
|
|
117
|
+
const: name,
|
|
118
|
+
description: `Component name identifier (must be "${name}")`
|
|
119
|
+
},
|
|
120
|
+
id: {
|
|
121
|
+
type: "string",
|
|
122
|
+
description: "Optional unique identifier for the component"
|
|
123
|
+
},
|
|
124
|
+
props: JSON.parse(JSON.stringify(config.schema))
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
if (containerNames.includes(name)) {
|
|
128
|
+
componentStructure.properties.children = {
|
|
129
|
+
type: "array",
|
|
130
|
+
description: "Children within this container",
|
|
131
|
+
items: {
|
|
132
|
+
$ref: "#/definitions/ComponentDefinition"
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
if (componentDefinitionSchema) {
|
|
136
|
+
componentStructure.definitions = {
|
|
137
|
+
ComponentDefinition: JSON.parse(
|
|
138
|
+
JSON.stringify(componentDefinitionSchema)
|
|
139
|
+
)
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
fixSchemaReferences(componentStructure);
|
|
144
|
+
componentStructure.additionalProperties = false;
|
|
145
|
+
return componentStructure;
|
|
146
|
+
}
|
|
147
|
+
async function exportSchemaToFile(schema, outputPath, options = {}) {
|
|
148
|
+
const { prettyPrint = true } = options;
|
|
149
|
+
const jsonSchema = prettyPrint ? JSON.stringify(schema, null, 2) : JSON.stringify(schema);
|
|
150
|
+
const fs = await import("fs/promises");
|
|
151
|
+
await fs.writeFile(outputPath, jsonSchema, "utf-8");
|
|
152
|
+
}
|
|
153
|
+
function createComponentSchemaObject(component, recursiveRef) {
|
|
154
|
+
const schema = {
|
|
155
|
+
name: Type.Literal(component.name),
|
|
156
|
+
id: Type.Optional(Type.String()),
|
|
157
|
+
enabled: Type.Optional(
|
|
158
|
+
Type.Boolean({
|
|
159
|
+
default: true,
|
|
160
|
+
description: "When false, this component is filtered out and not rendered. Defaults to true."
|
|
161
|
+
})
|
|
162
|
+
)
|
|
163
|
+
};
|
|
164
|
+
if (component.special?.hasSchemaField) {
|
|
165
|
+
schema.$schema = Type.Optional(Type.String({ format: "uri" }));
|
|
166
|
+
}
|
|
167
|
+
schema.props = component.propsSchema;
|
|
168
|
+
if (component.hasChildren && recursiveRef) {
|
|
169
|
+
schema.children = Type.Optional(Type.Array(recursiveRef));
|
|
170
|
+
}
|
|
171
|
+
return Type.Object(schema, { additionalProperties: false });
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export {
|
|
175
|
+
fixSchemaReferences,
|
|
176
|
+
convertToJsonSchema,
|
|
177
|
+
createComponentSchema,
|
|
178
|
+
exportSchemaToFile,
|
|
179
|
+
createComponentSchemaObject
|
|
180
|
+
};
|
|
181
|
+
//# sourceMappingURL=chunk-5J43F4XD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schemas/schema-utils.ts"],"sourcesContent":["import { Type, TSchema } from '@sinclair/typebox';\nimport type { ComponentDefinition } from '../types/components';\n\nexport interface ComponentSchemaConfig {\n schema: TSchema;\n title: string;\n description: string;\n requiresName?: boolean;\n enhanceForRichContent?: boolean;\n}\n\nfunction replaceRefs(\n obj: Record<string, unknown>,\n target: string,\n replacement: string\n): void {\n if (typeof obj !== 'object' || obj === null) return;\n if (Array.isArray(obj)) {\n obj.forEach((item) => {\n if (typeof item === 'object' && item !== null) {\n replaceRefs(item as Record<string, unknown>, target, replacement);\n }\n });\n return;\n }\n if (obj.$ref === target) {\n obj.$ref = replacement;\n }\n for (const value of Object.values(obj)) {\n if (typeof value === 'object' && value !== null) {\n replaceRefs(value as Record<string, unknown>, target, replacement);\n }\n }\n}\n\nexport function fixSchemaReferences(\n schema: Record<string, unknown>,\n rootDefinitionName = 'ComponentDefinition'\n): void {\n function traverse(obj: Record<string, unknown>, path = ''): void {\n if (typeof obj !== 'object' || obj === null) return;\n\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = path ? `${path}.${key}` : key;\n\n if (value && typeof value === 'object') {\n const schemaValue = value as Record<string, unknown>;\n\n if (\n schemaValue.type === 'array' &&\n schemaValue.items &&\n Object.keys(schemaValue.items).length === 0\n ) {\n schemaValue.items = {\n $ref: `#/definitions/${rootDefinitionName}`,\n };\n }\n\n if (\n schemaValue.type === 'array' &&\n schemaValue.items &&\n typeof schemaValue.items === 'object' &&\n '$ref' in schemaValue.items &&\n typeof (schemaValue.items as Record<string, unknown>).$ref === 'string' &&\n /^T\\d+$/.test((schemaValue.items as Record<string, unknown>).$ref as string)\n ) {\n schemaValue.items = {\n $ref: `#/definitions/${rootDefinitionName}`,\n };\n }\n\n if (\n typeof schemaValue.$ref === 'string' &&\n (/^T\\d+$/.test(schemaValue.$ref as string) ||\n schemaValue.$ref === rootDefinitionName)\n ) {\n schemaValue.$ref = `#/definitions/${rootDefinitionName}`;\n }\n\n if (\n key === '$id' &&\n typeof value === 'string' &&\n (/^T\\d+$/.test(value) || value === rootDefinitionName) &&\n currentPath !== `definitions.${rootDefinitionName}.$id`\n ) {\n delete obj[key];\n continue;\n }\n\n traverse(value as Record<string, unknown>, currentPath);\n }\n }\n }\n\n traverse(schema);\n}\n\nexport function convertToJsonSchema(\n schema: TSchema,\n options: {\n $schema?: string;\n $id?: string;\n title?: string;\n description?: string;\n definitions?: Record<string, unknown>;\n } = {}\n): Record<string, unknown> {\n const {\n $schema = 'https://json-schema.org/draft-07/schema#',\n $id,\n title,\n description,\n definitions = {},\n } = options;\n\n const schemaJson = JSON.parse(JSON.stringify(schema));\n\n if (\n schemaJson.$id &&\n typeof schemaJson.$id === 'string' &&\n /^T\\d+$/.test(schemaJson.$id)\n ) {\n const recursiveId = schemaJson.$id;\n delete schemaJson.$id;\n replaceRefs(schemaJson, recursiveId, '#');\n }\n\n const extractedDefinitions: Record<string, unknown> = { ...definitions };\n\n function extractRecursiveSchemas(\n obj: Record<string, unknown>,\n path = ''\n ): void {\n if (typeof obj !== 'object' || obj === null) return;\n\n for (const [key, value] of Object.entries(obj)) {\n if (value && typeof value === 'object') {\n const schemaValue = value as Record<string, unknown>;\n\n if (schemaValue.$id && typeof schemaValue.$id === 'string') {\n const definitionName = schemaValue.$id;\n\n if (path !== `definitions.${definitionName}`) {\n const { $id: _id, ...schemaWithoutId } = schemaValue; // eslint-disable-line @typescript-eslint/no-unused-vars\n extractedDefinitions[definitionName] = schemaWithoutId;\n obj[key] = { $ref: `#/definitions/${definitionName}` };\n extractRecursiveSchemas(\n schemaWithoutId,\n `definitions.${definitionName}`\n );\n continue;\n }\n }\n\n extractRecursiveSchemas(\n value as Record<string, unknown>,\n path ? `${path}.${key}` : key\n );\n }\n }\n }\n\n extractRecursiveSchemas(schemaJson);\n\n const jsonSchema: Record<string, unknown> = { $schema };\n\n if ($id) jsonSchema.$id = $id;\n\n Object.assign(jsonSchema, schemaJson);\n\n jsonSchema.$schema = $schema;\n if ($id) jsonSchema.$id = $id;\n if (title !== undefined) jsonSchema.title = title;\n if (description !== undefined) jsonSchema.description = description;\n\n if (Object.keys(extractedDefinitions).length > 0) {\n jsonSchema.definitions = extractedDefinitions;\n }\n\n fixSchemaReferences(jsonSchema);\n\n return jsonSchema;\n}\n\nexport function createComponentSchema(\n name: string,\n config: ComponentSchemaConfig,\n containerNames: string[],\n componentDefinitionSchema?: TSchema\n): Record<string, unknown> {\n const componentStructure: Record<string, unknown> = {\n $schema: 'https://json-schema.org/draft-07/schema#',\n $id: `${name}.schema.json`,\n title: config.title,\n description: config.description,\n type: 'object',\n required: ['name', 'props'],\n properties: {\n name: {\n type: 'string',\n const: name,\n description: `Component name identifier (must be \"${name}\")`,\n },\n id: {\n type: 'string',\n description: 'Optional unique identifier for the component',\n },\n props: JSON.parse(JSON.stringify(config.schema)),\n },\n };\n\n if (containerNames.includes(name)) {\n (componentStructure.properties as Record<string, unknown>).children = {\n type: 'array',\n description: 'Children within this container',\n items: {\n $ref: '#/definitions/ComponentDefinition',\n },\n };\n\n if (componentDefinitionSchema) {\n componentStructure.definitions = {\n ComponentDefinition: JSON.parse(\n JSON.stringify(componentDefinitionSchema)\n ),\n };\n }\n }\n\n fixSchemaReferences(componentStructure);\n componentStructure.additionalProperties = false;\n\n return componentStructure;\n}\n\nexport async function exportSchemaToFile(\n schema: Record<string, unknown>,\n outputPath: string,\n options: { prettyPrint?: boolean } = {}\n): Promise<void> {\n const { prettyPrint = true } = options;\n const jsonSchema = prettyPrint\n ? JSON.stringify(schema, null, 2)\n : JSON.stringify(schema);\n const fs = await import('fs/promises');\n await fs.writeFile(outputPath, jsonSchema, 'utf-8');\n}\n\n/**\n * Create a TypeBox schema object for any component definition.\n * Works for both docx and pptx components.\n */\nexport function createComponentSchemaObject(\n component: ComponentDefinition,\n recursiveRef?: TSchema\n): TSchema {\n const schema: Record<string, TSchema> = {\n name: Type.Literal(component.name),\n id: Type.Optional(Type.String()),\n enabled: Type.Optional(\n Type.Boolean({\n default: true,\n description:\n 'When false, this component is filtered out and not rendered. Defaults to true.',\n })\n ),\n };\n\n if (component.special?.hasSchemaField) {\n schema.$schema = Type.Optional(Type.String({ format: 'uri' }));\n }\n\n schema.props = component.propsSchema;\n\n if (component.hasChildren && recursiveRef) {\n schema.children = Type.Optional(Type.Array(recursiveRef));\n }\n\n return Type.Object(schema, { additionalProperties: false });\n}\n"],"mappings":"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","names":[]}
|