{"version":3,"sources":["../src/utils/files.ts","../src/core/consolidator.ts"],"names":["path","glob","readFile","writeFile","stat","copyFile","readFileContent"],"mappings":"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","file":"consolidator.cjs","sourcesContent":["/**\n * File utilities for Classpresso\n */\n\nimport { readFile, writeFile, stat, copyFile } from 'fs/promises';\nimport { glob } from 'glob';\nimport path from 'path';\nimport type { FileStats } from '../types/index.js';\n\n/**\n * Default file patterns to scan in build output\n *\n * These patterns support all major frameworks when pointing to their build directories:\n * - Next.js: --dir .next\n * - Astro: --dir dist\n * - Nuxt: --dir .output\n * - SvelteKit: --dir build (or .svelte-kit)\n * - Remix: --dir build\n * - Solid Start: --dir .output (or dist)\n * - Qwik: --dir dist\n * - Angular: --dir dist/[project-name]\n * - Gatsby: --dir public\n * - Vite/Vue/React: --dir dist\n * - Ember: --dir dist\n * - VitePress: --dir .vitepress/dist\n * - Docusaurus: --dir build\n * - Eleventy (11ty): --dir _site\n * - Hugo: --dir public\n * - Parcel: --dir dist\n * - Preact: --dir build (or dist)\n * - Gridsome: --dir dist\n * - RedwoodJS: --dir web/dist\n * - Webpack: --dir dist\n */\nexport const DEFAULT_PATTERNS = [\n  // === Next.js (.next directory) ===\n  // Client-side chunks\n  'static/chunks/**/*.js',\n  'static/css/**/*.css',\n  // Server components (Next.js App Router)\n  'server/app/**/*.js',\n  'server/app/**/*.html',\n  'server/app/**/*.rsc',\n  // Server chunks (contains Client Component code used for hydration)\n  'server/chunks/**/*.js',\n  // Standalone build (Next.js output: 'standalone')\n  'standalone/.next/static/chunks/**/*.js',\n  'standalone/.next/static/css/**/*.css',\n  'standalone/.next/server/app/**/*.js',\n  'standalone/.next/server/app/**/*.html',\n  'standalone/.next/server/app/**/*.rsc',\n  'standalone/.next/server/chunks/**/*.js',\n\n  // === Nuxt (.output directory) ===\n  'public/**/*.html',\n  'public/**/*.js',\n  'public/**/*.css',\n  'public/_nuxt/**/*.js',\n  'public/_nuxt/**/*.css',\n  'server/**/*.mjs',\n  'server/chunks/**/*.mjs',\n\n  // === SvelteKit (build directory) ===\n  // Static adapter output\n  '**/*.html',\n  '_app/**/*.js',\n  '_app/**/*.css',\n  // Node adapter output\n  'client/**/*.js',\n  'client/**/*.css',\n  'server/**/*.js',\n\n  // === Astro (dist directory) ===\n  '_astro/**/*.js',\n  '_astro/**/*.css',\n  // SSR/Hybrid build - Client assets\n  'client/_astro/**/*.js',\n  'client/_astro/**/*.css',\n\n  // === Remix (build directory) ===\n  'client/**/*.js',\n  'client/**/*.css',\n  'server/**/*.js',\n\n  // === Solid Start (.output or dist directory) ===\n  'public/**/*.html',\n  'public/**/*.js',\n  'public/**/*.css',\n  '_build/**/*.js',\n  '_build/**/*.css',\n\n  // === Qwik (dist directory) ===\n  'build/**/*.js',\n  'build/**/*.css',\n  'q-*.js',\n\n  // === Angular (dist/[project] directory) ===\n  // Angular 17+ uses browser subdirectory\n  'browser/**/*.js',\n  'browser/**/*.css',\n  'browser/**/*.html',\n  // Legacy Angular output\n  '*.js',\n  '*.css',\n  '*.html',\n\n  // === Gatsby (public directory) ===\n  'page-data/**/*.json',\n  '*.js',\n  '*.css',\n  '*.html',\n\n  // === Vite/Vue/React generic (dist directory) ===\n  'assets/**/*.js',\n  'assets/**/*.css',\n  'index.html',\n\n  // === Ember (dist directory) ===\n  'assets/**/*.js',\n  'assets/**/*.css',\n  '*.html',\n\n  // === VitePress (.vitepress/dist directory) ===\n  'assets/**/*.js',\n  'assets/**/*.css',\n  '**/*.html',\n\n  // === Docusaurus (build directory) ===\n  'assets/**/*.js',\n  'assets/**/*.css',\n  '**/*.html',\n\n  // === Eleventy/11ty (_site directory) ===\n  '**/*.html',\n  '**/*.js',\n  '**/*.css',\n\n  // === Hugo (public directory) ===\n  '**/*.html',\n  '**/*.js',\n  '**/*.css',\n\n  // === Parcel (dist directory) ===\n  '*.html',\n  '*.js',\n  '*.css',\n\n  // === Preact (build directory) ===\n  'bundle.js',\n  'bundle.*.js',\n  '*.css',\n  '*.html',\n\n  // === Gridsome (dist directory) ===\n  'assets/**/*.js',\n  'assets/**/*.css',\n  '**/*.html',\n\n  // === RedwoodJS (web/dist directory) ===\n  'static/**/*.js',\n  'static/**/*.css',\n  '*.html',\n\n  // === Webpack generic (dist directory) ===\n  '*.js',\n  '*.css',\n  '*.html',\n  'js/**/*.js',\n  'css/**/*.css',\n];\n\n/**\n * Find files matching patterns in a build directory\n */\nexport async function findFiles(\n  buildDir: string,\n  patterns: string[]\n): Promise<string[]> {\n  // Create full patterns and deduplicate\n  const globPatterns = [...new Set(patterns.map(p => path.join(buildDir, p)))];\n\n  // Use windowsPathsNoEscape for Windows compatibility\n  const allFiles = await glob(globPatterns, {\n    nodir: true,\n    windowsPathsNoEscape: true\n  });\n\n  // Remove duplicates (in case patterns overlap)\n  return [...new Set(allFiles)];\n}\n\n/**\n * Read file content as string\n */\nexport async function readFileContent(filePath: string): Promise<string> {\n  return readFile(filePath, 'utf-8');\n}\n\n/**\n * Write content to file\n */\nexport async function writeFileContent(\n  filePath: string,\n  content: string\n): Promise<void> {\n  await writeFile(filePath, content, 'utf-8');\n}\n\n/**\n * Get file size in bytes\n */\nexport async function getFileSize(filePath: string): Promise<number> {\n  const stats = await stat(filePath);\n  return stats.size;\n}\n\n/**\n * Create a backup of a file\n */\nexport async function backupFile(filePath: string): Promise<string> {\n  const backupPath = `${filePath}.classpresso-backup`;\n  await copyFile(filePath, backupPath);\n  return backupPath;\n}\n\n/**\n * Get file stats for a list of files\n */\nexport async function getFileStats(filePaths: string[]): Promise<FileStats[]> {\n  const stats: FileStats[] = [];\n\n  for (const filePath of filePaths) {\n    try {\n      const size = await getFileSize(filePath);\n      stats.push({\n        path: filePath,\n        originalSize: size,\n        modified: false,\n      });\n    } catch {\n      // Skip files that can't be read\n    }\n  }\n\n  return stats;\n}\n\n/**\n * Check if a file is a JavaScript file\n */\nexport function isJSFile(filePath: string): boolean {\n  return /\\.(js|mjs|cjs)$/.test(filePath);\n}\n\n/**\n * Check if a file is a CSS file\n */\nexport function isCSSFile(filePath: string): boolean {\n  return /\\.css$/.test(filePath);\n}\n\n/**\n * Check if a file is an HTML file\n */\nexport function isHTMLFile(filePath: string): boolean {\n  return /\\.(html|htm)$/.test(filePath);\n}\n\n/**\n * Check if a file is an RSC payload\n */\nexport function isRSCFile(filePath: string): boolean {\n  return /\\.rsc$/.test(filePath);\n}\n\n/**\n * Check if a file matches any exclusion pattern\n * Patterns can be glob-style (e.g., \"**\\/Demo*\", \"**\\/ClassTester*\")\n */\nexport function shouldExcludeFile(filePath: string, excludePatterns: string[]): boolean {\n  if (!excludePatterns || excludePatterns.length === 0) {\n    return false;\n  }\n\n  // Normalize path for consistent matching\n  const normalizedPath = filePath.replace(/\\\\/g, '/');\n\n  for (const pattern of excludePatterns) {\n    // Convert glob pattern to regex\n    // Support: ** (any path), * (any chars), ? (single char)\n    const regexPattern = pattern\n      .replace(/\\\\/g, '/')\n      .replace(/\\*\\*/g, '{{DOUBLESTAR}}')\n      .replace(/\\*/g, '[^/]*')\n      .replace(/\\?/g, '.')\n      .replace(/{{DOUBLESTAR}}/g, '.*');\n\n    const regex = new RegExp(regexPattern);\n    if (regex.test(normalizedPath)) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Filter files to exclude those matching exclusion patterns\n */\nexport function filterExcludedFiles(files: string[], excludePatterns: string[]): string[] {\n  if (!excludePatterns || excludePatterns.length === 0) {\n    return files;\n  }\n\n  return files.filter(filePath => !shouldExcludeFile(filePath, excludePatterns));\n}\n","/**\n * Consolidator - Creates consolidated class mappings\n */\n\nimport type {\n  ClasspressoConfig,\n  ConsolidationCandidate,\n  ClassMapping,\n  MappingManifest,\n  OptimizationMetrics,\n} from '../types/index.js';\nimport { writeFileContent } from '../utils/files.js';\nimport path from 'path';\n\n/**\n * Create class mappings from consolidation candidates\n */\nexport function createClassMappings(\n  candidates: ConsolidationCandidate[]\n): ClassMapping[] {\n  return candidates.map((candidate) => ({\n    original: candidate.classString,\n    consolidated: candidate.hashName,\n    classes: candidate.classes,\n    excludedClasses: candidate.excludedClasses,\n    cssDeclarations: '', // Will be filled by CSS generator\n    frequency: candidate.frequency,\n    bytesSaved: candidate.bytesSaved,\n  }));\n}\n\n/**\n * Build a lookup map from original class patterns to their consolidated names\n */\nexport function buildReplacementMap(\n  mappings: ClassMapping[]\n): Map<string, { consolidated: string; excludedClasses: string[] }> {\n  const map = new Map<string, { consolidated: string; excludedClasses: string[] }>();\n\n  for (const mapping of mappings) {\n    // Key is the sorted class string (without excluded classes)\n    const key = [...mapping.classes].sort().join(' ');\n    map.set(key, {\n      consolidated: mapping.consolidated,\n      excludedClasses: mapping.excludedClasses,\n    });\n  }\n\n  return map;\n}\n\n/**\n * Create and save the mapping manifest\n */\nexport async function saveMappingManifest(\n  mappings: ClassMapping[],\n  metrics: OptimizationMetrics,\n  config: ClasspressoConfig\n): Promise<string> {\n  const manifest: MappingManifest = {\n    version: '1.0.0',\n    tool: 'classpresso',\n    buildDir: config.buildDir,\n    created: new Date().toISOString(),\n    config: {\n      minOccurrences: config.minOccurrences,\n      minClasses: config.minClasses,\n      hashPrefix: config.hashPrefix,\n      hashLength: config.hashLength,\n    },\n    mappings,\n    metrics,\n  };\n\n  const manifestPath = path.join(config.buildDir, 'classpresso-manifest.json');\n  await writeFileContent(manifestPath, JSON.stringify(manifest, null, 2));\n\n  return manifestPath;\n}\n\n/**\n * Load an existing manifest\n */\nexport async function loadMappingManifest(\n  buildDir: string\n): Promise<MappingManifest | null> {\n  const manifestPath = path.join(buildDir, 'classpresso-manifest.json');\n\n  try {\n    const { readFileContent } = await import('../utils/files.js');\n    const content = await readFileContent(manifestPath);\n    return JSON.parse(content) as MappingManifest;\n  } catch {\n    return null;\n  }\n}\n"]}