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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | 250x 250x 250x 250x 250x 250x 250x 250x 250x 250x 250x 250x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 3x 3x 3x 3x 3x 5x 2x 2x 5x 5x 5x 5x 5x 2x 2x 2x 5x 250x 250x 250x 250x 250x 250x 250x 250x 4x 4x 4x 4x 4x 4x 4x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 2x 2x 4x 250x 250x 250x 250x 250x 250x 250x 250x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 250x 250x 250x 250x 250x 250x 250x 250x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 250x 250x 250x 250x 250x 250x 250x 250x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import fs from 'fs';
import path from 'path';
import { parseName, fail } from '../utils.js';
import { cyan, gray, green } from '../colors.js';
/**
* Automatically removes imports, registrations, and mount statements for a class from src/main.app.js.
* @param {object} cli
* @param {string} className
* @param {string} folderName
*/
export function unregisterFromMainApp(cli, className, folderName) {
const mainPath = path.join(cli.baseDir, cli.config.srcDir, 'main.app.js');
if (!fs.existsSync(mainPath)) return;
const content = fs.readFileSync(mainPath, 'utf-8');
// Remove import statements
const importRegex = new RegExp(
`^import\\s+(?:${className}|\\{\\s*${className}\\s*\\})\\s+from\\s+['"].*?${folderName}.*?['"];?\\r?\\n?`,
'm',
);
const generalImportRegex = new RegExp(
`^import\\s+(?:${className}|\\{\\s*${className}\\s*\\})\\s+from\\s+['"].*?['"];?\\r?\\n?`,
'm',
);
// Remove app.register calls
const registerRegex = new RegExp(
`^\\s*app\\.register\\(\\s*['"]${className}['"]\\s*,\\s*${className}\\s*\\);?\\r?\\n?`,
'm',
);
// Remove app.mount calls and their commented versions
const mountRegex = new RegExp(`^\\s*(?://\\s*)?app\\.mount\\(\\s*['"]${className}['"]\\s*\\);?\\r?\\n?`, 'm');
const commentedMountRegex = new RegExp(
`^\\s*(?://\\s*)?app\\.mount\\(\\s*['"]${className}['"]\\s*\\);?\\s*//\\s*Uncomment\\s+to\\s+mount\\s+this\\s+component\\r?\\n?`,
'm',
);
let newContent = content
.replace(commentedMountRegex, '')
.replace(mountRegex, '')
.replace(registerRegex, '')
.replace(importRegex, '');
if (newContent === content) {
newContent = content
.replace(commentedMountRegex, '')
.replace(mountRegex, '')
.replace(registerRegex, '')
.replace(generalImportRegex, '');
} else {
newContent = newContent.replace(generalImportRegex, '');
}
// Clean up extra consecutive newlines
newContent = newContent.replace(/\n{3,}/g, '\n\n');
if (content !== newContent) {
fs.writeFileSync(mainPath, newContent);
console.log(green(`✅ Cleaned up imports and registrations for '${className}' in ${cli.config.srcDir}/main.app.js`));
}
}
/**
* Destroys a component folder and template files, and unregisters it from main.app.js.
* @param {object} cli
* @param {string} name
* @param {boolean} [dryRun]
*/
export function destroyComponent(cli, name, dryRun = false) {
if (!name) {
fail('Please provide a component name (e.g., avenx d my-component)');
return;
}
const { capitalizedName, folderFileName: lowerName } = parseName(name);
const compDir = path.join(cli.baseDir, cli.config.srcDir, 'components', lowerName);
const testPath = path.join(compDir, `${lowerName}.component.test.js`);
if (dryRun) {
console.log(cyan(`🧪 [Dry Run] Component '${lowerName}' files would be deleted:`));
console.log(gray(`[DRY-RUN] Would delete: ${cli.config.srcDir}/components/${lowerName}/${lowerName}.component.js`));
console.log(
gray(`[DRY-RUN] Would delete: ${cli.config.srcDir}/components/${lowerName}/${lowerName}.component.css`),
);
if (fs.existsSync(testPath)) {
console.log(
gray(`[DRY-RUN] Would delete: ${cli.config.srcDir}/components/${lowerName}/${lowerName}.component.test.js`),
);
}
console.log(gray(`[DRY-RUN] Would delete: ${cli.config.srcDir}/components/${lowerName}/`));
console.log(
cyan(`🧪 [Dry Run] ${cli.config.srcDir}/main.app.js would be updated to remove registrations/imports for '${capitalizedName}'.`),
);
console.log(cyan('🧪 [Dry Run] No files were deleted or modified.'));
return;
}
if (fs.existsSync(compDir)) {
fs.rmSync(compDir, { recursive: true, force: true });
console.log(green(`✅ Component '${lowerName}' directory deleted at ${cli.config.srcDir}/components/${lowerName}/`));
} else {
console.log(gray(`ℹ️ Component '${lowerName}' directory was not found.`));
}
unregisterFromMainApp(cli, capitalizedName, lowerName);
}
/**
* Destroys a page class and template files, and unregisters it from main.app.js.
* @param {object} cli
* @param {string} name
* @param {boolean} [dryRun]
*/
export function destroyPage(cli, name, dryRun = false) {
if (!name) {
fail('Please provide a page name (e.g., avenx d page home)');
return;
}
const { capitalizedName, folderFileName: lowerName } = parseName(name);
const pageDir = path.join(cli.baseDir, cli.config.srcDir, 'pages');
const jsPath = path.join(pageDir, `${lowerName}.page.js`);
const cssPath = path.join(pageDir, `${lowerName}.page.css`);
if (dryRun) {
console.log(cyan(`🧪 [Dry Run] Page '${lowerName}' files would be deleted:`));
console.log(gray(`[DRY-RUN] Would delete: ${cli.config.srcDir}/pages/${lowerName}.page.js`));
console.log(gray(`[DRY-RUN] Would delete: ${cli.config.srcDir}/pages/${lowerName}.page.css`));
console.log(
cyan(`🧪 [Dry Run] ${cli.config.srcDir}/main.app.js would be updated to remove imports/registrations/routes for '${capitalizedName}'.`),
);
console.log(cyan('🧪 [Dry Run] No files were deleted or modified.'));
return;
}
let deletedAny = false;
if (fs.existsSync(jsPath)) {
fs.rmSync(jsPath, { force: true });
console.log(` Deleted: ${cli.config.srcDir}/pages/${lowerName}.page.js`);
deletedAny = true;
}
if (fs.existsSync(cssPath)) {
fs.rmSync(cssPath, { force: true });
console.log(` Deleted: ${cli.config.srcDir}/pages/${lowerName}.page.css`);
deletedAny = true;
}
if (deletedAny) {
console.log(green(`✅ Page '${capitalizedName}' files deleted.`));
} else {
console.log(gray(`ℹ️ Page '${capitalizedName}' files were not found.`));
}
unregisterFromMainApp(cli, capitalizedName, lowerName);
}
/**
* Destroys a Bridge class file.
* @param {object} cli
* @param {string} name
* @param {boolean} [dryRun]
*/
export function destroyBridge(cli, name, dryRun = false) {
if (!name) {
fail('Please provide a bridge name (e.g., avenx d bridge auth)');
return;
}
const { capitalizedName: baseName, folderFileName: lowerName } = parseName(name);
const capitalizedName = baseName + 'Bridge';
const globalDir = path.join(cli.baseDir, cli.config.srcDir, 'global');
const bridgePath = path.join(globalDir, `${lowerName}.bridge.js`);
if (dryRun) {
console.log(cyan(`🧪 [Dry Run] Bridge '${capitalizedName}' file would be deleted:`));
console.log(gray(`[DRY-RUN] Would delete: ${cli.config.srcDir}/global/${lowerName}.bridge.js`));
console.log(
cyan(`🧪 [Dry Run] ${cli.config.srcDir}/main.app.js would be updated to remove imports/registrations for '${capitalizedName}'.`),
);
console.log(cyan('🧪 [Dry Run] No files were deleted or modified.'));
return;
}
if (fs.existsSync(bridgePath)) {
fs.rmSync(bridgePath, { force: true });
console.log(green(`✅ Bridge '${capitalizedName}' file deleted at ${cli.config.srcDir}/global/${lowerName}.bridge.js`));
} else {
console.log(gray(`ℹ️ Bridge '${capitalizedName}' file was not found.`));
}
unregisterFromMainApp(cli, capitalizedName, lowerName);
}
/**
* Destroys a Guard class file.
* @param {object} cli
* @param {string} name
* @param {boolean} [dryRun]
*/
export function destroyGuard(cli, name, dryRun = false) {
if (!name) {
fail('Please provide a guard name (e.g., avenx d guard auth)');
return;
}
const { capitalizedName: baseName, folderFileName: lowerName } = parseName(name);
const capitalizedName = baseName + 'Guard';
const guardDir = path.join(cli.baseDir, cli.config.srcDir, 'guards');
const guardPath = path.join(guardDir, `${lowerName}.guard.js`);
if (dryRun) {
console.log(cyan(`🧪 [Dry Run] Guard '${capitalizedName}' file would be deleted:`));
console.log(gray(`[DRY-RUN] Would delete: ${cli.config.srcDir}/guards/${lowerName}.guard.js`));
console.log(
cyan(`🧪 [Dry Run] ${cli.config.srcDir}/main.app.js would be updated to remove imports/registrations for '${capitalizedName}'.`),
);
console.log(cyan('🧪 [Dry Run] No files were deleted or modified.'));
return;
}
if (fs.existsSync(guardPath)) {
fs.rmSync(guardPath, { force: true });
console.log(green(`✅ Guard '${capitalizedName}' file deleted at ${cli.config.srcDir}/guards/${lowerName}.guard.js`));
} else {
console.log(gray(`ℹ️ Guard '${capitalizedName}' file was not found.`));
}
unregisterFromMainApp(cli, capitalizedName, lowerName);
}
|