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 114 115 116 117 118 | 1x 1x 1x 1x 1x 1x 24x 24x 24x 24x 24x 24x 1x 17x 17x 17x 17x 17x 17x 85x 85x 85x 85x 85x 85x 85x 85x 85x 85x 85x 85x 85x 85x 85x 85x 85x 85x 85x 17x 17x 1x 10x 10x 10x 10x 10x 1x 67x 67x 67x 67x 67x 67x 242x 242x 242x 242x 44x 44x 242x 198x 198x 198x 198x 242x 67x | import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs'; import { dirname, join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import type { TemplateInfo, TemplateVariables } from './types'; import { replaceTemplateVariables } from './utils/index'; const __dirname = dirname(fileURLToPath(import.meta.url)); /** * Get version of esmx from package.json */ export function getEsmxVersion(): string { try { const packageJsonPath = resolve(__dirname, '../package.json'); const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')); return packageJson.version || 'latest'; } catch (error) { console.warn('Failed to read esmx version, using latest version'); return 'latest'; } } /** * Get list of available templates */ export function getAvailableTemplates(): TemplateInfo[] { const templateDir = resolve(__dirname, '../template'); const templates: TemplateInfo[] = []; const templateFolders = readdirSync(templateDir, { withFileTypes: true }) .filter((dirent) => dirent.isDirectory()) .map((dirent) => dirent.name); for (const folder of templateFolders) { // Use folder name as display name const name = folder; // Try to read description from package.json const packageJsonPath = resolve(templateDir, folder, 'package.json'); let description = `${name} template`; if (existsSync(packageJsonPath)) { try { const packageJson = JSON.parse( readFileSync(packageJsonPath, 'utf-8') ); if (packageJson.description) { description = packageJson.description; } templates.push({ folder, name, description }); } catch (error) { // JSON parsing failed, skip this template console.warn( `Warning: Failed to parse package.json for template '${folder}', skipping.` ); } } } // Sort by name alphabetically return templates.sort((a, b) => a.name.localeCompare(b.name)); } /** * Check if directory is empty (ignoring hidden files) */ export function isDirectoryEmpty(dirPath: string): boolean { if (!existsSync(dirPath)) { return true; } const files = readdirSync(dirPath); // Only consider non-hidden files and directories const nonHiddenFiles = files.filter((file) => !file.startsWith('.')); return nonHiddenFiles.length === 0; } /** * Copy template files to target directory with variable replacement */ export function copyTemplateFiles( templatePath: string, targetPath: string, variables: TemplateVariables ): void { const files = readdirSync(templatePath); for (const file of files) { const filePath = join(templatePath, file); const targetFilePath = join(targetPath, file); const stat = statSync(filePath); if (stat.isDirectory()) { mkdirSync(targetFilePath, { recursive: true }); copyTemplateFiles(filePath, targetFilePath, variables); } else { let content = readFileSync(filePath, 'utf-8'); // Replace all template variables using the utility function content = replaceTemplateVariables(content, variables); writeFileSync(targetFilePath, content); } } } |