UNPKG

@elsikora/setup-wizard

Version:

Setup Wizard - CLI scaffolding utility

164 lines (161 loc) 7.49 kB
#!/usr/bin/env node 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 { STYLELINT_CONFIG_CORE_DEPENDENCIES } from '../constant/stylelint-config-core-dependencies.constant.js'; import { STYLELINT_CONFIG_FILE_NAME } from '../constant/stylelint-config-file-name.constant.js'; import { STYLELINT_CONFIG_FILE_NAMES } from '../constant/stylelint-config-file-names.constant.js'; import { STYLELINT_CONFIG_IGNORE_FILE_NAME } from '../constant/stylelint-config-ignore-file-name.constant.js'; import { STYLELINT_CONFIG_IGNORE_PATHS } from '../constant/stylelint-config-ignore-paths.constant.js'; import { STYLELINT_CONFIG } from '../constant/stylelint-config.constant.js'; import { PackageJsonService } from './package-json.service.js'; /** * Service for setting up and managing Stylelint configuration. * Provides functionality to enforce consistent CSS/SCSS code style and format * through Stylelint configuration and npm scripts. */ class StylelintModuleService { /** 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 StylelintModuleService. * @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 Stylelint 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 = ["Existing Stylelint configuration files detected:"]; messageLines.push(""); if (existingFiles.length > 0) { for (const file of existingFiles) { messageLines.push(`- ${file}`); } } messageLines.push("", "Do you want to delete them?"); 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("Existing Stylelint configuration files detected. Setup aborted."); return false; } } return true; } /** * Installs and configures Stylelint. * Sets up configuration files and npm scripts for CSS/SCSS linting. * @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.setupStylelint(); return { wasInstalled: true }; } catch (error) { this.CLI_INTERFACE_SERVICE.handleError("Failed to complete Stylelint setup", error); throw error; } } /** * Determines if Stylelint should be installed. * Asks the user if they want to set up Stylelint 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("Do you want to set up Stylelint for your project?", await this.CONFIG_SERVICE.isModuleEnabled(EModule.STYLELINT)); } catch (error) { this.CLI_INTERFACE_SERVICE.handleError("Failed to get user confirmation", error); return false; } } /** * Creates Stylelint configuration files. * Generates the main config file and ignore file. */ async createConfigs() { await this.FILE_SYSTEM_SERVICE.writeFile(STYLELINT_CONFIG_FILE_NAME, STYLELINT_CONFIG, "utf8"); await this.FILE_SYSTEM_SERVICE.writeFile(STYLELINT_CONFIG_IGNORE_FILE_NAME, STYLELINT_CONFIG_IGNORE_PATHS.join("\n"), "utf8"); } /** * Displays a summary of the Stylelint setup results. * Lists generated scripts and configuration files. */ displaySetupSummary() { const summary = ["Stylelint configuration has been created.", "", "Generated scripts:", "- npm run lint:style", "- npm run lint:style:fix", "", "You can customize the configuration in these files:", `- ${STYLELINT_CONFIG_FILE_NAME}`, `- ${STYLELINT_CONFIG_IGNORE_FILE_NAME}`]; this.CLI_INTERFACE_SERVICE.note("Stylelint Setup", summary.join("\n")); } /** * Finds existing Stylelint configuration files. * @returns Promise resolving to an array of file paths for existing configuration files */ async findExistingConfigFiles() { const existingFiles = []; for (const file of STYLELINT_CONFIG_FILE_NAMES) { if (await this.FILE_SYSTEM_SERVICE.isPathExists(file)) { existingFiles.push(file); } } return existingFiles; } /** * Sets up npm scripts for Stylelint. * Adds scripts for linting and fixing CSS/SCSS files. */ async setupScripts() { await this.PACKAGE_JSON_SERVICE.addScript("lint:style", 'stylelint "**/*.{css,scss}"'); await this.PACKAGE_JSON_SERVICE.addScript("lint:style:fix", 'stylelint "**/*.{css,scss}" --fix'); } /** * Sets up Stylelint configuration. * Installs dependencies, creates config files, and adds npm scripts. */ async setupStylelint() { this.CLI_INTERFACE_SERVICE.startSpinner("Setting up Stylelint configuration..."); try { await this.PACKAGE_JSON_SERVICE.installPackages(STYLELINT_CONFIG_CORE_DEPENDENCIES, "latest", EPackageJsonDependencyType.DEV); await this.createConfigs(); await this.setupScripts(); this.CLI_INTERFACE_SERVICE.stopSpinner("Stylelint configuration completed successfully!"); this.displaySetupSummary(); } catch (error) { this.CLI_INTERFACE_SERVICE.stopSpinner("Failed to setup Stylelint configuration"); throw error; } } } export { StylelintModuleService }; //# sourceMappingURL=stylelint-module.service.js.map