@elsikora/setup-wizard
Version:
Setup Wizard - CLI scaffolding utility
167 lines (164 loc) • 7.81 kB
JavaScript
import { EModule } from '../../domain/enum/module.enum.js';
import { EPackageJsonDependencyType } from '../../domain/enum/package-json-dependency-type.enum.js';
import { NodeCommandService } from '../../infrastructure/service/node-command.service.js';
import { PRETTIER_CONFIG_FILE_NAME } from '../constant/prettier/config-file-name.constant.js';
import { PRETTIER_CONFIG } from '../constant/prettier/config.constant.js';
import { PRETTIER_CONFIG_CORE_DEPENDENCIES } from '../constant/prettier/core-dependencies.constant.js';
import { PRETTIER_CONFIG_FILE_NAMES } from '../constant/prettier/file-names.constant.js';
import { PRETTIER_CONFIG_IGNORE_FILE_NAME } from '../constant/prettier/ignore-file-name.constant.js';
import { PRETTIER_CONFIG_IGNORE_PATHS } from '../constant/prettier/ignore-paths.constant.js';
import { PRETTIER_CONFIG_MESSAGES } from '../constant/prettier/messages.constant.js';
import { PRETTIER_CONFIG_SCRIPTS } from '../constant/prettier/scripts.constant.js';
import { PRETTIER_CONFIG_SUMMARY } from '../constant/prettier/summary.constant.js';
import { PackageJsonService } from './package-json.service.js';
/**
* Service for setting up and managing Prettier code formatting.
* Provides functionality to enforce consistent code style and formatting
* across the project through Prettier configuration.
*/
class PrettierModuleService {
/** CLI interface service for user interaction */
CLI_INTERFACE_SERVICE;
/** Command service for executing shell commands */
COMMAND_SERVICE;
/** Configuration service for managing app configuration */
CONFIG_SERVICE;
/** File system service for file operations */
FILE_SYSTEM_SERVICE;
/** Service for managing package.json */
PACKAGE_JSON_SERVICE;
/**
* Initializes a new instance of the PrettierModuleService.
* @param cliInterfaceService - Service for CLI user interactions
* @param fileSystemService - Service for file system operations
* @param configService - Service for managing app configuration
*/
constructor(cliInterfaceService, fileSystemService, configService) {
this.CLI_INTERFACE_SERVICE = cliInterfaceService;
this.FILE_SYSTEM_SERVICE = fileSystemService;
this.COMMAND_SERVICE = new NodeCommandService(cliInterfaceService);
this.PACKAGE_JSON_SERVICE = new PackageJsonService(fileSystemService, this.COMMAND_SERVICE);
this.CONFIG_SERVICE = configService;
}
/**
* Handles existing Prettier setup.
* Checks for existing configuration files and asks if user wants to remove them.
* @returns Promise resolving to true if setup should proceed, false otherwise
*/
async handleExistingSetup() {
const existingFiles = await this.findExistingConfigFiles();
if (existingFiles.length > 0) {
const messageLines = [PRETTIER_CONFIG_MESSAGES.existingFilesDetected];
messageLines.push("");
if (existingFiles.length > 0) {
for (const file of existingFiles) {
messageLines.push(`- ${file}`);
}
}
messageLines.push("", PRETTIER_CONFIG_MESSAGES.deleteFilesQuestion);
const shouldDelete = await this.CLI_INTERFACE_SERVICE.confirm(messageLines.join("\n"), true);
if (shouldDelete) {
await Promise.all(existingFiles.map((file) => this.FILE_SYSTEM_SERVICE.deleteFile(file)));
}
else {
this.CLI_INTERFACE_SERVICE.warn(PRETTIER_CONFIG_MESSAGES.existingFilesAborted);
return false;
}
}
return true;
}
/**
* Installs and configures Prettier.
* Sets up configuration files and npm scripts for code formatting.
* @returns Promise resolving to the module setup result
*/
async install() {
try {
if (!(await this.shouldInstall())) {
return { wasInstalled: false };
}
if (!(await this.handleExistingSetup())) {
return { wasInstalled: false };
}
await this.setupPrettier();
return { wasInstalled: true };
}
catch (error) {
this.CLI_INTERFACE_SERVICE.handleError(PRETTIER_CONFIG_MESSAGES.failedSetupError, error);
throw error;
}
}
/**
* Determines if Prettier should be installed.
* Asks the user if they want to set up Prettier for their project.
* Uses the saved config value as default if it exists.
* @returns Promise resolving to true if the module should be installed, false otherwise
*/
async shouldInstall() {
try {
return await this.CLI_INTERFACE_SERVICE.confirm(PRETTIER_CONFIG_MESSAGES.confirmSetup, await this.CONFIG_SERVICE.isModuleEnabled(EModule.PRETTIER));
}
catch (error) {
this.CLI_INTERFACE_SERVICE.handleError(PRETTIER_CONFIG_MESSAGES.failedConfirmation, error);
return false;
}
}
/**
* Creates Prettier configuration files.
* Generates the main config file and ignore file.
*/
async createConfigs() {
await this.FILE_SYSTEM_SERVICE.writeFile(PRETTIER_CONFIG_FILE_NAME, PRETTIER_CONFIG, "utf8");
await this.FILE_SYSTEM_SERVICE.writeFile(PRETTIER_CONFIG_IGNORE_FILE_NAME, PRETTIER_CONFIG_IGNORE_PATHS.join("\n"), "utf8");
}
/**
* Displays a summary of the Prettier setup results.
* Lists generated scripts and configuration files.
*/
displaySetupSummary() {
const summary = [PRETTIER_CONFIG_MESSAGES.prettierConfigCreated, "", PRETTIER_CONFIG_MESSAGES.generatedScriptsLabel, PRETTIER_CONFIG_SUMMARY.formatDescription, PRETTIER_CONFIG_SUMMARY.formatFixDescription, "", PRETTIER_CONFIG_SUMMARY.customizeFilesLabel, `- ${PRETTIER_CONFIG_FILE_NAME}`, `- ${PRETTIER_CONFIG_IGNORE_FILE_NAME}`];
this.CLI_INTERFACE_SERVICE.note(PRETTIER_CONFIG_MESSAGES.setupCompleteTitle, summary.join("\n"));
}
/**
* Finds existing Prettier configuration files.
* @returns Promise resolving to an array of file paths for existing configuration files
*/
async findExistingConfigFiles() {
const existingFiles = [];
for (const file of PRETTIER_CONFIG_FILE_NAMES) {
if (await this.FILE_SYSTEM_SERVICE.isPathExists(file)) {
existingFiles.push(file);
}
}
return existingFiles;
}
/**
* Sets up Prettier configuration.
* Installs dependencies, creates config files, and adds npm scripts.
*/
async setupPrettier() {
this.CLI_INTERFACE_SERVICE.startSpinner(PRETTIER_CONFIG_MESSAGES.settingUpSpinner);
try {
await this.PACKAGE_JSON_SERVICE.installPackages(PRETTIER_CONFIG_CORE_DEPENDENCIES, "latest", EPackageJsonDependencyType.DEV);
await this.createConfigs();
await this.setupScripts();
this.CLI_INTERFACE_SERVICE.stopSpinner(PRETTIER_CONFIG_MESSAGES.setupCompleteSpinner);
this.displaySetupSummary();
}
catch (error) {
this.CLI_INTERFACE_SERVICE.stopSpinner(PRETTIER_CONFIG_MESSAGES.failedSetupSpinner);
throw error;
}
}
/**
* Sets up npm scripts for Prettier.
* Adds scripts for checking and fixing code formatting.
*/
async setupScripts() {
await this.PACKAGE_JSON_SERVICE.addScript(PRETTIER_CONFIG_SCRIPTS.format.name, PRETTIER_CONFIG_SCRIPTS.format.command);
await this.PACKAGE_JSON_SERVICE.addScript(PRETTIER_CONFIG_SCRIPTS.formatFix.name, PRETTIER_CONFIG_SCRIPTS.formatFix.command);
}
}
export { PrettierModuleService };
//# sourceMappingURL=prettier-module.service.js.map