All files / packages/design-system/scripts/validation capture-baseline-core.js

100% Statements 58/58
100% Branches 26/26
100% Functions 10/10
100% Lines 56/56

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 1141x               2x       4x 1x     3x 3x 3x       3x 3x 3x 3x 3x   3x                   5x       4x 4x 4x   4x       2x 2x 2x 2x 2x       2x 3x 3x   3x 3x   3x 3x   3x         3x 1x     2x 2x 2x   2x 2x 2x 2x   2x 1x     1x 1x 1x 1x   1x 1x   1x 1x 1x 1x   1x 1x 1x   1x            
import path from 'node:path';
import fs from 'fs-extra';
import chalk from 'chalk';
import { pathToFileURL } from 'node:url';
 
import { findFiles, createManifest, writeManifest } from './lib/baseline-file-utils.js';
 
export function resolveConfigPath(configArg, cwd = process.cwd()) {
  return path.resolve(cwd, configArg);
}
 
export async function loadConfig(configPath) {
  if (!fs.existsSync(configPath)) {
    throw new Error(`Config file not found: ${configPath}`);
  }
 
  const configUrl = pathToFileURL(configPath).href;
  const configModule = await import(configUrl);
  return configModule.default || configModule;
}
 
export function resolveCaptureSettings(config, cliArgs, cwd = process.cwd()) {
  const name = config.name || 'Baseline';
  const sourceDir = path.resolve(cwd, cliArgs.source || config.source);
  const baselineDir = path.resolve(cwd, config.baseline);
  const globPattern = config.glob || '**/*';
  const plugins = config.plugins || [];
 
  return {
    name,
    sourceDir,
    baselineDir,
    globPattern,
    plugins,
  };
}
 
export function collectBeforeCaptureHooks(plugins = []) {
  return plugins.filter((plugin) => typeof plugin.beforeCapture === 'function').map((plugin) => plugin.beforeCapture);
}
 
export function applyBeforeCaptureHooks(content, file, hooks = []) {
  let updatedContent = content;
  for (const hook of hooks) {
    updatedContent = hook(updatedContent, file) || updatedContent;
  }
  return updatedContent;
}
 
export function prepareBaselineDirectory(baselineDir) {
  fs.removeSync(baselineDir);
  fs.ensureDirSync(baselineDir);
  const baselineFilesDir = path.join(baselineDir, 'files');
  fs.ensureDirSync(baselineFilesDir);
  return baselineFilesDir;
}
 
export function captureFiles({ files, sourceDir, baselineFilesDir, beforeCaptureHooks, log = console.log }) {
  for (const file of files) {
    const sourcePath = path.join(sourceDir, file);
    const destPath = path.join(baselineFilesDir, file);
 
    const sourceContent = fs.readFileSync(sourcePath, 'utf8');
    const content = applyBeforeCaptureHooks(sourceContent, file, beforeCaptureHooks);
 
    fs.ensureDirSync(path.dirname(destPath));
    fs.writeFileSync(destPath, content, 'utf8');
 
    log(chalk.green(`   āœ“ ${file}`));
  }
}
 
export async function captureBaseline(cliArgs, { cwd = process.cwd(), log = console.log } = {}) {
  if (!cliArgs?.config) {
    throw new Error('Config argument is required');
  }
 
  const configPath = resolveConfigPath(cliArgs.config, cwd);
  const config = await loadConfig(configPath);
  const { name, sourceDir, baselineDir, globPattern, plugins } = resolveCaptureSettings(config, cliArgs, cwd);
 
  log(chalk.blue(`šŸ“ø Capturing baseline: ${name}\n`));
  log(chalk.gray(`   Source: ${sourceDir}`));
  log(chalk.gray(`   Baseline: ${baselineDir}`));
  log(chalk.gray(`   Pattern: ${globPattern}\n`));
 
  if (!fs.existsSync(sourceDir)) {
    throw new Error(`Source directory not found: ${sourceDir}`);
  }
 
  log(chalk.gray('   Cleaning baseline directory...'));
  const baselineFilesDir = prepareBaselineDirectory(baselineDir);
  const files = findFiles(sourceDir, globPattern);
  log(chalk.gray(`   Found ${files.length} file(s) to capture.\n`));
 
  const beforeCaptureHooks = collectBeforeCaptureHooks(plugins);
  captureFiles({ files, sourceDir, baselineFilesDir, beforeCaptureHooks, log });
 
  const manifest = createManifest(baselineFilesDir, globPattern);
  manifest.name = name;
  manifest.source = sourceDir;
  writeManifest(baselineDir, manifest);
 
  log(chalk.green(`\nāœ… Baseline captured successfully!`));
  log(chalk.gray(`   Files: ${files.length}`));
  log(chalk.gray(`   Location: ${baselineDir}\n`));
 
  return {
    filesCount: files.length,
    baselineDir,
    sourceDir,
  };
}