style: format with prettier

This commit is contained in:
Carlos 2024-08-13 20:05:53 -04:00
parent 7422ddf34b
commit 0e72a35ba7
13 changed files with 2058 additions and 98 deletions

15
.eslintrc.js Normal file
View File

@ -0,0 +1,15 @@
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: ['eslint:recommended', 'plugin:prettier/recommended'],
parserOptions: {
ecmaVersion: 12,
sourceType: 'module',
},
rules: {
'prettier/prettier': 'error',
},
};

7
.prettierrc Normal file
View File

@ -0,0 +1,7 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"printWidth": 80
}

View File

@ -1,4 +1,3 @@
# Contributor Covenant Code of Conduct # Contributor Covenant Code of Conduct
## Our Pledge ## Our Pledge
@ -46,18 +45,22 @@ All community leaders are obligated to respect the privacy and security of the r
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction ### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
### 2. Warning ### 2. Warning
**Community Impact**: A violation through a single incident or series of actions. **Community Impact**: A violation through a single incident or series of actions.
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
### 3. Temporary Ban ### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
### 4. Permanent Ban ### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the community. **Consequence**: A permanent ban from any sort of public interaction within the community.

View File

@ -1,4 +1,3 @@
# React Crafter # React Crafter
**React Crafter** is a CLI tool designed to quickly scaffold a modern React application with TypeScript, Ant Design, Sass, Webpack, and essential development tools like Husky and linters pre-configured. This tool simplifies the initial setup, allowing developers to start coding with best practices from the get-go. **React Crafter** is a CLI tool designed to quickly scaffold a modern React application with TypeScript, Ant Design, Sass, Webpack, and essential development tools like Husky and linters pre-configured. This tool simplifies the initial setup, allowing developers to start coding with best practices from the get-go.
@ -49,57 +48,75 @@ npx react-crafter awesome-project
Heres a summary of the commands you can use after setting up your project: Heres a summary of the commands you can use after setting up your project:
1. **Start Development Server**: 1. **Start Development Server**:
```bash ```bash
npm start npm start
``` ```
Starts the development server with Webpack. The project is served using Webpack Dev Server with the configuration specified in `webpack.config.js`. Starts the development server with Webpack. The project is served using Webpack Dev Server with the configuration specified in `webpack.config.js`.
2. **Build for Production**: 2. **Build for Production**:
```bash ```bash
npm run build npm run build
``` ```
Builds the project for production. Webpack compiles the project and outputs the optimized bundle in the `/dist` directory. Builds the project for production. Webpack compiles the project and outputs the optimized bundle in the `/dist` directory.
3. **Run Tests**: 3. **Run Tests**:
```bash ```bash
npm test npm test
``` ```
Placeholder for running tests. Currently, it does not run any tests but can be customized to run Jest or other test suites. Placeholder for running tests. Currently, it does not run any tests but can be customized to run Jest or other test suites.
4. **Run Tests in Watch Mode**: 4. **Run Tests in Watch Mode**:
```bash ```bash
npm run test:dev npm run test:dev
``` ```
Runs tests in watch mode using React Scripts. Suitable for a test-driven development approach. Runs tests in watch mode using React Scripts. Suitable for a test-driven development approach.
5. **Format Staged Files**: 5. **Format Staged Files**:
```bash ```bash
npm run pretty-quick npm run pretty-quick
``` ```
Formats all staged files using Prettier. Ensures that code is consistently formatted before committing. Formats all staged files using Prettier. Ensures that code is consistently formatted before committing.
6. **Lint Entire Codebase**: 6. **Lint Entire Codebase**:
```bash ```bash
npm run lint:prettier npm run lint:prettier
``` ```
Checks the format of the entire codebase using a custom script. It can be used to ensure that all files adhere to Prettiers formatting rules. Checks the format of the entire codebase using a custom script. It can be used to ensure that all files adhere to Prettiers formatting rules.
7. **Format Entire Codebase**: 7. **Format Entire Codebase**:
```bash ```bash
npm run prettier npm run prettier
``` ```
Formats the entire codebase using Prettier based on the configuration in `.prettierrc`. Formats the entire codebase using Prettier based on the configuration in `.prettierrc`.
8. **Format & Commit**: 8. **Format & Commit**:
```bash ```bash
npm run prettier:commit npm run prettier:commit
``` ```
Applies Prettier formatting to staged files before committing. Ensures that committed code is properly formatted. Applies Prettier formatting to staged files before committing. Ensures that committed code is properly formatted.
9. **Eject Project**: 9. **Eject Project**:
```bash ```bash
npm run eject npm run eject
``` ```
Ejects the project from Create React App. This command exposes the underlying configuration files for full control but cannot be undone. Ejects the project from Create React App. This command exposes the underlying configuration files for full control but cannot be undone.
10. **Prepare Husky**: 10. **Prepare Husky**:
@ -132,12 +149,14 @@ This feature ensures you can start working in your preferred environment immedia
We welcome contributions to React Crafter! If you have ideas, find bugs, or want to improve the project, please feel free to contribute. Here's how you can get involved: We welcome contributions to React Crafter! If you have ideas, find bugs, or want to improve the project, please feel free to contribute. Here's how you can get involved:
### 1. Fork the Repository ### 1. Fork the Repository
Start by forking the repository to your own GitHub account: Start by forking the repository to your own GitHub account:
1. Navigate to the [React Crafter GitHub repository](#). 1. Navigate to the [React Crafter GitHub repository](#).
2. Click the "Fork" button in the top right corner. 2. Click the "Fork" button in the top right corner.
### 2. Clone Your Fork ### 2. Clone Your Fork
Clone your forked repository to your local machine: Clone your forked repository to your local machine:
```bash ```bash
@ -146,6 +165,7 @@ cd react-crafter
``` ```
### 3. Create a New Branch ### 3. Create a New Branch
Create a new branch for your feature or bug fix: Create a new branch for your feature or bug fix:
```bash ```bash
@ -153,9 +173,11 @@ git checkout -b feature/your-feature-name
``` ```
### 4. Make Changes ### 4. Make Changes
Make your changes or improvements in your new branch. Follow the existing code style and conventions. Make your changes or improvements in your new branch. Follow the existing code style and conventions.
### 5. Test Your Changes ### 5. Test Your Changes
Before submitting your changes, make sure everything works as expected: Before submitting your changes, make sure everything works as expected:
```bash ```bash
@ -163,6 +185,7 @@ npm run test
``` ```
### 6. Commit and Push ### 6. Commit and Push
Commit your changes with a descriptive commit message: Commit your changes with a descriptive commit message:
```bash ```bash
@ -172,15 +195,19 @@ git push origin feature/your-feature-name
``` ```
### 7. Create a Pull Request ### 7. Create a Pull Request
Go to the original repository and click on the "Pull Requests" tab. Click "New Pull Request" and select your branch. Provide a description of your changes and submit the pull request. Go to the original repository and click on the "Pull Requests" tab. Click "New Pull Request" and select your branch. Provide a description of your changes and submit the pull request.
### 8. Review Process ### 8. Review Process
Your pull request will be reviewed by the maintainers. You may be asked to make additional changes or clarifications before your code is merged. Your pull request will be reviewed by the maintainers. You may be asked to make additional changes or clarifications before your code is merged.
### 9. Celebrate 🎉 ### 9. Celebrate 🎉
Once your pull request is merged, youve officially contributed to React Crafter! Thank you for your contribution. Once your pull request is merged, youve officially contributed to React Crafter! Thank you for your contribution.
### Code of Conduct ### Code of Conduct
Please note that we have a [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [cargdev@gmail.com](mailto:cargdev@gmail.com). Please note that we have a [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [cargdev@gmail.com](mailto:cargdev@gmail.com).
## License ## License

25
check-format.js Normal file
View File

@ -0,0 +1,25 @@
const { exec } = require('child_process');
const { promisify } = require('util');
const execPromise = promisify(exec);
async function run() {
// Dynamically import the ES Module
const ora = (await import('ora')).default;
const spinner = ora('✨ Checking code formatting...').start();
try {
const { stdout } = await execPromise(
'npm run pretty-quick --check . --config .prettierrc'
);
spinner.succeed('✅ Code formatting check passed.');
console.log(stdout);
} catch (error) {
spinner.fail('❌ Code formatting check failed.');
console.error(error.message);
process.exit(1);
}
}
run();

190
index.js
View File

@ -29,8 +29,14 @@ function createApp(projectDirectory) {
if (fs.existsSync(root)) { if (fs.existsSync(root)) {
console.clear(); console.clear();
console.log(chalk.red.bold('❌ Error: Directory already exists!')); console.log(chalk.red.bold('❌ Error: Directory already exists!'));
console.log(chalk.yellow(`\nThe directory ${chalk.blue(root)} already exists.`)); console.log(
console.log(chalk.cyan('Please choose a different project name or delete the existing directory.')); chalk.yellow(`\nThe directory ${chalk.blue(root)} already exists.`)
);
console.log(
chalk.cyan(
'Please choose a different project name or delete the existing directory.'
)
);
return; // Exit the function if the directory exists return; // Exit the function if the directory exists
} }
@ -41,7 +47,9 @@ function createApp(projectDirectory) {
fs.mkdirSync(root); fs.mkdirSync(root);
process.chdir(root); process.chdir(root);
const spinner = ora('⏳ Installing packages. This might take a couple of minutes.').start(); const spinner = ora(
'⏳ Installing packages. This might take a couple of minutes.'
).start();
execSync('npx create-react-app . --template typescript', { stdio: 'ignore' }); execSync('npx create-react-app . --template typescript', { stdio: 'ignore' });
@ -89,7 +97,11 @@ function askUserWhereToOpen(directory) {
openInNeovim(directory); openInNeovim(directory);
break; break;
default: default:
console.log(chalk.yellow('Project setup complete. You can manually open the project if needed.')); console.log(
chalk.yellow(
'Project setup complete. You can manually open the project if needed.'
)
);
} }
}); });
} }
@ -102,12 +114,18 @@ function openInTerminal(directory) {
spawn('open', ['-a', 'Terminal', directory]); spawn('open', ['-a', 'Terminal', directory]);
} else if (platform === 'win32') { } else if (platform === 'win32') {
// Windows // Windows
spawn('cmd.exe', ['/c', 'start', 'cmd.exe', '/K', `cd /d ${directory}`], { shell: true }); spawn('cmd.exe', ['/c', 'start', 'cmd.exe', '/K', `cd /d ${directory}`], {
shell: true,
});
} else if (platform === 'linux') { } else if (platform === 'linux') {
// Linux // Linux
spawn('gnome-terminal', ['--working-directory=' + directory]); spawn('gnome-terminal', ['--working-directory=' + directory]);
} else { } else {
console.log(chalk.red('Unsupported platform. Please manually navigate to the directory.')); console.log(
chalk.red(
'Unsupported platform. Please manually navigate to the directory.'
)
);
} }
} }
@ -124,36 +142,80 @@ function printCommandSummary() {
console.log(chalk.cyan('\nAvailable Commands:')); console.log(chalk.cyan('\nAvailable Commands:'));
console.log(chalk.green('1. 🚀 npm start')); console.log(chalk.green('1. 🚀 npm start'));
console.log(chalk.white(' Starts the development server with Webpack. The project is served using Webpack Dev Server with the configuration specified in webpack.config.js.')); console.log(
chalk.white(
' Starts the development server with Webpack. The project is served using Webpack Dev Server with the configuration specified in webpack.config.js.'
)
);
console.log(chalk.green('\n2. 🛠️ npm run build')); console.log(chalk.green('\n2. 🛠️ npm run build'));
console.log(chalk.white(' Builds the project for production. Webpack compiles the project and outputs the optimized bundle in the /dist directory.')); console.log(
chalk.white(
' Builds the project for production. Webpack compiles the project and outputs the optimized bundle in the /dist directory.'
)
);
console.log(chalk.green('\n3. 🧪 npm test')); console.log(chalk.green('\n3. 🧪 npm test'));
console.log(chalk.white(' Placeholder for running tests. Currently, it does not run any tests but can be customized to run Jest or other test suites.')); console.log(
chalk.white(
' Placeholder for running tests. Currently, it does not run any tests but can be customized to run Jest or other test suites.'
)
);
console.log(chalk.green('\n4. 🧪 npm run test:dev')); console.log(chalk.green('\n4. 🧪 npm run test:dev'));
console.log(chalk.white(' Runs tests in watch mode using React Scripts. Suitable for a test-driven development approach.')); console.log(
chalk.white(
' Runs tests in watch mode using React Scripts. Suitable for a test-driven development approach.'
)
);
console.log(chalk.green('\n5. 🎨 npm run pretty-quick')); console.log(chalk.green('\n5. 🎨 npm run pretty-quick'));
console.log(chalk.white(' Formats all staged files using Prettier. Ensures that code is consistently formatted before committing.')); console.log(
chalk.white(
' Formats all staged files using Prettier. Ensures that code is consistently formatted before committing.'
)
);
console.log(chalk.green('\n6. 🔍 npm run lint:prettier')); console.log(chalk.green('\n6. 🔍 npm run lint:prettier'));
console.log(chalk.white(' Checks the format of the entire codebase using a custom script. It can be used to ensure that all files adhere to Prettiers formatting rules.')); console.log(
chalk.white(
' Checks the format of the entire codebase using a custom script. It can be used to ensure that all files adhere to Prettiers formatting rules.'
)
);
console.log(chalk.green('\n7. ✨ npm run prettier')); console.log(chalk.green('\n7. ✨ npm run prettier'));
console.log(chalk.white(' Formats the entire codebase using Prettier based on the configuration in .prettierrc.')); console.log(
chalk.white(
' Formats the entire codebase using Prettier based on the configuration in .prettierrc.'
)
);
console.log(chalk.green('\n8. ✨ npm run prettier:commit')); console.log(chalk.green('\n8. ✨ npm run prettier:commit'));
console.log(chalk.white(' Applies Prettier formatting to staged files before committing. Ensures that committed code is properly formatted.')); console.log(
chalk.white(
' Applies Prettier formatting to staged files before committing. Ensures that committed code is properly formatted.'
)
);
console.log(chalk.green('\n9. 🚨 npm run eject')); console.log(chalk.green('\n9. 🚨 npm run eject'));
console.log(chalk.white(' Ejects the project from Create React App. This command exposes the underlying configuration files for full control but cannot be undone.')); console.log(
chalk.white(
' Ejects the project from Create React App. This command exposes the underlying configuration files for full control but cannot be undone.'
)
);
console.log(chalk.green('\n10. 🛡️ npm run prepare')); console.log(chalk.green('\n10. 🛡️ npm run prepare'));
console.log(chalk.white(' Installs Husky hooks. This script is automatically run after dependencies are installed, setting up Git hooks for the project.')); console.log(
chalk.white(
' Installs Husky hooks. This script is automatically run after dependencies are installed, setting up Git hooks for the project.'
)
);
console.log(chalk.yellow('\n🎉 Your project is ready! Use the above commands to start working on your new React app.')); console.log(
chalk.yellow(
'\n🎉 Your project is ready! Use the above commands to start working on your new React app.'
)
);
} }
function runPrettierCommit() { function runPrettierCommit() {
@ -194,22 +256,24 @@ function deletePreCommitHook() {
} }
function updatePackageJson() { function updatePackageJson() {
const spinner = ora('📝 Updating package.json with custom scripts...').start(); const spinner = ora(
'📝 Updating package.json with custom scripts...'
).start();
const packageJsonPath = path.resolve('package.json'); const packageJsonPath = path.resolve('package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
packageJson.scripts = { packageJson.scripts = {
"start": "webpack serve --config webpack.config.js --mode development", start: 'webpack serve --config webpack.config.js --mode development',
"build": "webpack --config webpack.config.js --mode production", build: 'webpack --config webpack.config.js --mode production',
"test": "echo \"Error: no test specified\" && exit 0", test: 'echo "Error: no test specified" && exit 0',
"test:dev": "react-scripts test", 'test:dev': 'react-scripts test',
"pretty-quick": "pretty-quick", 'pretty-quick': 'pretty-quick',
"lint:prettier": "node check-format.js", 'lint:prettier': 'node check-format.js',
"prettier": "prettier --write . --config .prettierrc", prettier: 'prettier --write . --config .prettierrc',
"prettier:commit": "node prettier-commit.js", 'prettier:commit': 'node prettier-commit.js',
"eject": "react-scripts eject", eject: 'react-scripts eject',
"prepare": "husky install" prepare: 'husky install',
}; };
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
@ -220,18 +284,42 @@ function copyPreConfiguredFiles(destinationPath) {
const spinner = ora('📁 Copying pre-configured files...').start(); const spinner = ora('📁 Copying pre-configured files...').start();
const filesToCopy = [ const filesToCopy = [
{ src: path.resolve(__dirname, 'pre-files/check-format.js'), dest: path.join(destinationPath, 'check-format.js') }, {
{ src: path.resolve(__dirname, 'pre-files/commit-msg-linter.js'), dest: path.join(destinationPath, '.husky/commit-msg-linter.js') }, src: path.resolve(__dirname, 'pre-files/check-format.js'),
{ src: path.resolve(__dirname, 'pre-files/lint-check.js'), dest: path.join(destinationPath, '.husky/lint-check.js') }, dest: path.join(destinationPath, 'check-format.js'),
{ src: path.resolve(__dirname, 'pre-files/prettier-commit.js'), dest: path.join(destinationPath, 'prettier-commit.js') }, },
{ src: path.resolve(__dirname, 'pre-files/webpack.config.js'), dest: path.join(destinationPath, 'webpack.config.js') }, {
{ src: path.resolve(__dirname, 'pre-files/.babelrc'), dest: path.join(destinationPath, '.babelrc') }, src: path.resolve(__dirname, 'pre-files/commit-msg-linter.js'),
{ src: path.resolve(__dirname, 'pre-files/.eslintrc.js'), dest: path.join(destinationPath, '.eslintrc.js') }, dest: path.join(destinationPath, '.husky/commit-msg-linter.js'),
{ src: path.resolve(__dirname, 'pre-files/.prettierrc'), dest: path.join(destinationPath, '.prettierrc') }, },
{
src: path.resolve(__dirname, 'pre-files/lint-check.js'),
dest: path.join(destinationPath, '.husky/lint-check.js'),
},
{
src: path.resolve(__dirname, 'pre-files/prettier-commit.js'),
dest: path.join(destinationPath, 'prettier-commit.js'),
},
{
src: path.resolve(__dirname, 'pre-files/webpack.config.js'),
dest: path.join(destinationPath, 'webpack.config.js'),
},
{
src: path.resolve(__dirname, 'pre-files/.babelrc'),
dest: path.join(destinationPath, '.babelrc'),
},
{
src: path.resolve(__dirname, 'pre-files/.eslintrc.js'),
dest: path.join(destinationPath, '.eslintrc.js'),
},
{
src: path.resolve(__dirname, 'pre-files/.prettierrc'),
dest: path.join(destinationPath, '.prettierrc'),
},
// Add more files here if needed // Add more files here if needed
]; ];
filesToCopy.forEach(file => { filesToCopy.forEach((file) => {
fs.copyFileSync(file.src, file.dest); fs.copyFileSync(file.src, file.dest);
}); });
@ -245,13 +333,19 @@ function copyPreConfiguredFiles(destinationPath) {
function installDependencies() { function installDependencies() {
const spinner = ora('🔄 Installing additional dependencies...').start(); const spinner = ora('🔄 Installing additional dependencies...').start();
execSync('npm install @babel/core @babel/preset-env @babel/preset-react @reduxjs/toolkit @testing-library/jest-dom @testing-library/react @testing-library/user-event @types/jest @types/node @types/react @types/react-dom ajv antd babel-loader css-loader jest playwright react react-dom react-redux react-scripts redux sass sass-loader style-loader typescript web-vitals webpack webpack-cli', { stdio: 'ignore' }); execSync(
'npm install @babel/core @babel/preset-env @babel/preset-react @reduxjs/toolkit @testing-library/jest-dom @testing-library/react @testing-library/user-event @types/jest @types/node @types/react @types/react-dom ajv antd babel-loader css-loader jest playwright react react-dom react-redux react-scripts redux sass sass-loader style-loader typescript web-vitals webpack webpack-cli',
{ stdio: 'ignore' }
);
spinner.succeed('✅ Additional dependencies installed.'); spinner.succeed('✅ Additional dependencies installed.');
} }
function installDevDependencies() { function installDevDependencies() {
const spinner = ora('🔄 Installing additional dev dependencies...').start(); const spinner = ora('🔄 Installing additional dev dependencies...').start();
execSync('npm install --save-dev @babel/plugin-proposal-private-property-in-object ora prettier @commitlint/cli @commitlint/config-conventional @svgr/webpack dotenv dotenv-webpack husky url-loader webpack-dev-server pretty-quick', { stdio: 'ignore' }); execSync(
'npm install --save-dev @babel/plugin-proposal-private-property-in-object ora prettier @commitlint/cli @commitlint/config-conventional @svgr/webpack dotenv dotenv-webpack husky url-loader webpack-dev-server pretty-quick',
{ stdio: 'ignore' }
);
spinner.succeed('✅ Additional dev dependencies installed.'); spinner.succeed('✅ Additional dev dependencies installed.');
} }
@ -287,16 +381,18 @@ function setupCommitlint() {
const spinner = ora('🔍 Setting up Commitlint...').start(); const spinner = ora('🔍 Setting up Commitlint...').start();
const commitMsg = `#!/bin/sh const commitMsg = `#!/bin/sh
. "$(dirname "$0")/_/husky.sh" . "$(dirname "$0")/_/husky.sh"
node ./.husky/commit-msg-linter.js "$1"` node ./.husky/commit-msg-linter.js "$1"`;
const commitLintMsgLinter = `module.exports = { const commitLintMsgLinter = `module.exports = {
extends: ['@commitlint/config-conventional'], extends: ['@commitlint/config-conventional'],
};` };`;
const prePush = `#!/bin/sh const prePush = `#!/bin/sh
. "$(dirname "$0")/_/husky.sh" . "$(dirname "$0")/_/husky.sh"
node .husky/lint-check.js` node .husky/lint-check.js`;
execSync('npm install @commitlint/{config-conventional,cli} --save-dev', { stdio: 'ignore' }); execSync('npm install @commitlint/{config-conventional,cli} --save-dev', {
stdio: 'ignore',
});
execSync('touch .husky/commit-msg', { stdio: 'ignore' }); execSync('touch .husky/commit-msg', { stdio: 'ignore' });
execSync('touch .husky/pre-push', { stdio: 'ignore' }); execSync('touch .husky/pre-push', { stdio: 'ignore' });
execSync('chmod +x .husky/commit-msg', { stdio: 'ignore' }); execSync('chmod +x .husky/commit-msg', { stdio: 'ignore' });
@ -315,10 +411,10 @@ function setupRedux() {
'src/store', 'src/store',
'src/store/slices', 'src/store/slices',
'src/store/middleware', 'src/store/middleware',
'src/store/selectors' 'src/store/selectors',
]; ];
reduxStructure.forEach(dir => { reduxStructure.forEach((dir) => {
fs.mkdirSync(dir, { recursive: true }); fs.mkdirSync(dir, { recursive: true });
}); });
@ -365,10 +461,10 @@ function createAtomicStructure() {
'src/components/molecules', 'src/components/molecules',
'src/components/organisms', 'src/components/organisms',
'src/components/templates', 'src/components/templates',
'src/components/pages' 'src/components/pages',
]; ];
atomicStructure.forEach(dir => { atomicStructure.forEach((dir) => {
fs.mkdirSync(dir, { recursive: true }); fs.mkdirSync(dir, { recursive: true });
}); });
spinner.succeed('🏗️ Atomic design structure created.'); spinner.succeed('🏗️ Atomic design structure created.');

View File

@ -1,7 +1,7 @@
module.exports = { module.exports = {
testEnvironment: "node", // Set up the environment (node, jsdom, etc.) testEnvironment: 'node', // Set up the environment (node, jsdom, etc.)
verbose: true, // Show detailed test results verbose: true, // Show detailed test results
coverageDirectory: "coverage", // Directory for code coverage reports coverageDirectory: 'coverage', // Directory for code coverage reports
collectCoverage: true, // Collect coverage information collectCoverage: true, // Collect coverage information
coverageReporters: ["text", "lcov"], // Reporters for coverage coverageReporters: ['text', 'lcov'], // Reporters for coverage
}; };

863
node_modules/.package-lock.json generated vendored

File diff suppressed because it is too large Load Diff

867
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,10 @@
"author": "Carlos Gutierrez <cargdev@gmail.com>", "author": "Carlos Gutierrez <cargdev@gmail.com>",
"scripts": { "scripts": {
"start": "node index.js", "start": "node index.js",
"test": "jest" "test": "jest",
"lint:prettier": "node check-format.js",
"prettier": "prettier --write . --config .prettierrc",
"prettier:commit": "node prettier-commit.js"
}, },
"dependencies": { "dependencies": {
"chalk": "^4.1.0", "chalk": "^4.1.0",
@ -45,7 +48,11 @@
"babel-loader": "^8.2.2", "babel-loader": "^8.2.2",
"css-loader": "^5.1.1", "css-loader": "^5.1.1",
"dotenv-webpack": "^7.0.2", "dotenv-webpack": "^7.0.2",
"eslint": "^9.9.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"jest": "^29.7.0", "jest": "^29.7.0",
"prettier": "^3.3.3",
"sass-loader": "^11.0.1", "sass-loader": "^11.0.1",
"style-loader": "^2.0.0", "style-loader": "^2.0.0",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",

45
prettier-commit.js Normal file
View File

@ -0,0 +1,45 @@
const { execSync } = require('child_process');
(async () => {
const ora = (await import('ora')).default;
const spinner = ora('Running Prettier...').start();
try {
// Run Prettier
execSync('npm run prettier', { stdio: 'inherit' });
spinner.succeed('Prettier has formatted the files.');
// Check for changes
spinner.start('Checking for changes...');
const changes = execSync('git status --porcelain', { encoding: 'utf-8' });
if (changes) {
spinner.succeed('Changes detected.');
// Read the latest commit message to ensure uniqueness
const latestCommitMessage = execSync('git log -1 --pretty=%B', {
encoding: 'utf-8',
}).trim();
// Generate a unique commit message
let commitMessage = 'style: format with prettier';
if (latestCommitMessage.includes(commitMessage)) {
commitMessage = `style: format with prettier ${Date.now()}`;
}
// Add and commit changes
spinner.start('Adding changes to Git...');
execSync('git add .', { stdio: 'inherit' });
spinner.succeed('Changes added to Git.');
spinner.start('Committing changes...');
execSync(`git commit -m "${commitMessage}"`, { stdio: 'inherit' });
spinner.succeed('Changes committed.');
} else {
spinner.info('No changes detected by Prettier.');
}
} catch (error) {
spinner.fail('An error occurred while running Prettier.');
console.error(error);
process.exit(1);
}
})();

View File

@ -7,11 +7,16 @@ jest.mock('child_process');
describe('installDependencies', () => { describe('installDependencies', () => {
it('should install dependencies without errors', () => { it('should install dependencies without errors', () => {
const execSyncMock = jest.spyOn(child_process, 'execSync').mockImplementation(() => {}); const execSyncMock = jest
.spyOn(child_process, 'execSync')
.mockImplementation(() => {});
installDependencies(); installDependencies();
expect(execSyncMock).toHaveBeenCalledWith(expect.stringContaining('npm install'), expect.anything()); expect(execSyncMock).toHaveBeenCalledWith(
expect.stringContaining('npm install'),
expect.anything()
);
execSyncMock.mockRestore(); execSyncMock.mockRestore();
}); });