@iamandersonp/prettier-staged 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +17 -0
- package/.git-hooks/pre-commit +24 -2
- package/.git-hooks/pre-commit-sample +25 -2
- package/.versionrc.json +2 -2
- package/CHANGELOG.md +23 -17
- package/README.md +103 -12
- package/package.json +7 -3
- package/src/index.js +62 -2
- package/tests/index.test.js +133 -2
package/.env.example
CHANGED
|
@@ -12,3 +12,20 @@
|
|
|
12
12
|
# Nota: Las comillas son opcionales y serán removidas automáticamente
|
|
13
13
|
|
|
14
14
|
HOOKS_DIR=.git-hooks
|
|
15
|
+
|
|
16
|
+
# Configuración de extensiones de archivos para formateo con Prettier
|
|
17
|
+
#
|
|
18
|
+
# EXTENSIONS define qué tipos de archivos serán formateados por Prettier.
|
|
19
|
+
# Debe ser una lista separada por comas. Si no se especifica, se usará
|
|
20
|
+
# el valor por defecto: html,ts,scss,css,json,js
|
|
21
|
+
#
|
|
22
|
+
# Ejemplos:
|
|
23
|
+
# EXTENSIONS=html,ts,scss,css,json,js # Valor por defecto
|
|
24
|
+
# EXTENSIONS=js,jsx,ts,tsx # Solo archivos JavaScript/TypeScript
|
|
25
|
+
# EXTENSIONS="vue,svelte,astro" # Con comillas dobles
|
|
26
|
+
# EXTENSIONS='md,mdx,html' # Con comillas simples
|
|
27
|
+
# EXTENSIONS=js, ts, css, scss # Con espacios (serán removidos automáticamente)
|
|
28
|
+
#
|
|
29
|
+
# Nota: Las comillas y espacios extra son opcionales y serán removidos automáticamente
|
|
30
|
+
|
|
31
|
+
EXTENSIONS=html,js,ts,scss,css,json
|
package/.git-hooks/pre-commit
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
#
|
|
3
|
+
# Función para leer extensiones desde .env
|
|
4
|
+
get_extensions_from_env() {
|
|
5
|
+
local env_file=".env"
|
|
6
|
+
local default_extensions="html|ts|scss|css|json|js"
|
|
7
|
+
|
|
8
|
+
if [ ! -f "$env_file" ]; then
|
|
9
|
+
echo "$default_extensions"
|
|
10
|
+
return
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
# Buscar EXTENSIONS en .env
|
|
14
|
+
local extensions=$(grep "^EXTENSIONS=" "$env_file" 2>/dev/null | cut -d'=' -f2- | tr -d '"' | tr -d "'")
|
|
15
|
+
|
|
16
|
+
if [ -n "$extensions" ]; then
|
|
17
|
+
# Convertir comas a | para el regex
|
|
18
|
+
echo "$extensions" | sed 's/,/|/g' | sed 's/ //g'
|
|
19
|
+
else
|
|
20
|
+
echo "$default_extensions"
|
|
21
|
+
fi
|
|
22
|
+
}
|
|
3
23
|
|
|
4
24
|
if git ls-files -u | grep -q .; then
|
|
5
|
-
echo "⚠️ Merge in progress
|
|
25
|
+
echo "⚠️ Merge in progress. Skipping Prettier to avoid issues."
|
|
6
26
|
exit 0
|
|
7
27
|
fi
|
|
8
28
|
|
|
@@ -12,7 +32,9 @@ npm run test:coverage
|
|
|
12
32
|
|
|
13
33
|
npm run prettier-staged
|
|
14
34
|
|
|
15
|
-
|
|
35
|
+
# Obtener extensiones desde .env y construir patrón dinámico
|
|
36
|
+
EXTENSIONS_PATTERN=$(get_extensions_from_env)
|
|
37
|
+
STAGED_FILES=$(git diff --name-only --cached --diff-filter=ACM | grep -E "\.($EXTENSIONS_PATTERN)$")
|
|
16
38
|
|
|
17
39
|
if [ -n "$STAGED_FILES" ]; then
|
|
18
40
|
echo "$STAGED_FILES" | xargs git add
|
|
@@ -1,14 +1,37 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
#
|
|
3
3
|
|
|
4
|
+
# Función para leer extensiones desde .env
|
|
5
|
+
get_extensions_from_env() {
|
|
6
|
+
local env_file=".env"
|
|
7
|
+
local default_extensions="html|ts|scss|css|json|js"
|
|
8
|
+
|
|
9
|
+
if [ ! -f "$env_file" ]; then
|
|
10
|
+
echo "$default_extensions"
|
|
11
|
+
return
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
# Buscar EXTENSIONS en .env
|
|
15
|
+
local extensions=$(grep "^EXTENSIONS=" "$env_file" 2>/dev/null | cut -d'=' -f2- | tr -d '"' | tr -d "'")
|
|
16
|
+
|
|
17
|
+
if [ -n "$extensions" ]; then
|
|
18
|
+
# Convertir comas a | para el regex
|
|
19
|
+
echo "$extensions" | sed 's/,/|/g' | sed 's/ //g'
|
|
20
|
+
else
|
|
21
|
+
echo "$default_extensions"
|
|
22
|
+
fi
|
|
23
|
+
}
|
|
24
|
+
|
|
4
25
|
if git ls-files -u | grep -q .; then
|
|
5
|
-
echo "⚠️ Merge in progress
|
|
26
|
+
echo "⚠️ Merge in progress. Skipping Prettier to avoid issues."
|
|
6
27
|
exit 0
|
|
7
28
|
fi
|
|
8
29
|
|
|
9
30
|
npm run prettier-staged
|
|
10
31
|
|
|
11
|
-
|
|
32
|
+
# Obtener extensiones desde .env y construir patrón dinámico
|
|
33
|
+
EXTENSIONS_PATTERN=$(get_extensions_from_env)
|
|
34
|
+
STAGED_FILES=$(git diff --name-only --cached --diff-filter=ACM | grep -E "\.($EXTENSIONS_PATTERN)$")
|
|
12
35
|
|
|
13
36
|
if [ -n "$STAGED_FILES" ]; then
|
|
14
37
|
echo "$STAGED_FILES" | xargs git add
|
package/.versionrc.json
CHANGED
|
@@ -9,6 +9,6 @@
|
|
|
9
9
|
{ "type": "perf", "hidden": true },
|
|
10
10
|
{ "type": "test", "hidden": true }
|
|
11
11
|
],
|
|
12
|
-
"commitUrlFormat": "https://github.com/iamandersonp/
|
|
13
|
-
"compareUrlFormat": "https://github.com/iamandersonp/
|
|
12
|
+
"commitUrlFormat": "https://github.com/iamandersonp/prettier-staged.git/commits/{{hash}}",
|
|
13
|
+
"compareUrlFormat": "https://github.com/iamandersonp/prettier-staged.git/compare/{{previousTag}}...{{currentTag}}"
|
|
14
14
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -2,48 +2,54 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
### [0.3.1](https://github.com/iamandersonp/prettier-staged.git/compare/v0.3.0...v0.3.1) (2026-04-07)
|
|
7
6
|
|
|
8
7
|
### Bug Fixes
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
### [0.1.1](https://github.com/iamandersonp/preetier-staged/compare/v0.1.0...v0.1.1) (2026-04-06)
|
|
9
|
+
- :zap: pre-commit get extensions from .env ([06a66c4](https://github.com/iamandersonp/prettier-staged.git/commits/06a66c44b9029a0844a4245c51c2b342b31cf567))
|
|
13
10
|
|
|
11
|
+
## [0.3.0](https://github.com/iamandersonp/prettier-staged.git/compare/v0.2.0...v0.3.0) (2026-04-07)
|
|
14
12
|
|
|
15
13
|
### Features
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
- :sparkles: configurable extensions ([55ff5cb](https://github.com/iamandersonp/prettier-staged.git/commits/55ff5cb0c3276591e209979207610c4b48b04b62))
|
|
18
16
|
|
|
17
|
+
## [0.2.0](https://github.com/iamandersonp/prettier-staged/compare/v0.1.1...v0.2.0) (2026-04-07)
|
|
19
18
|
|
|
20
19
|
### Bug Fixes
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
## [0.1.0](https://github.com/iamandersonp/preetier-staged/compare/v0.0.7...v0.1.0) (2026-04-06)
|
|
21
|
+
- :rocket: rename to prettier-staged for consistence ([d7ae9f4](https://github.com/iamandersonp/prettier-staged/commits/d7ae9f40006e0040ee5045f3f642a6f02c860db2))
|
|
25
22
|
|
|
23
|
+
### [0.1.1](https://github.com/iamandersonp/prettier-staged/compare/v0.1.0...v0.1.1) (2026-04-06)
|
|
26
24
|
|
|
27
25
|
### Features
|
|
28
26
|
|
|
29
|
-
|
|
27
|
+
- :sparkles: instalation hook folder from .env file ([2414b31](https://github.com/iamandersonp/prettier-staged/commits/2414b317c6c6c40bd6818738e20cc8b6091fad5e))
|
|
28
|
+
|
|
29
|
+
### Bug Fixes
|
|
30
|
+
|
|
31
|
+
- :zap: instalation hook folder ([5acc701](https://github.com/iamandersonp/prettier-staged/commits/5acc701139e9f0bf7cdc0a0714e4c7285093efcc))
|
|
32
|
+
|
|
33
|
+
## [0.1.0](https://github.com/iamandersonp/prettier-staged/compare/v0.0.7...v0.1.0) (2026-04-06)
|
|
30
34
|
|
|
31
|
-
###
|
|
35
|
+
### Features
|
|
32
36
|
|
|
33
|
-
|
|
37
|
+
- :sparkles: add installation hook to copy sample pre-commit hook ([8fd317d](https://github.com/iamandersonp/prettier-staged/commits/8fd317d17b122cd6067c86e2ce7f187e89deaf38))
|
|
34
38
|
|
|
35
|
-
### [0.0.
|
|
39
|
+
### [0.0.5](https://github.com/iamandersonp/prettier-staged/compare/v0.0.4...v0.0.5) (2026-04-01)
|
|
36
40
|
|
|
41
|
+
### [0.0.4](https://github.com/iamandersonp/prettier-staged/compare/v0.0.3...v0.0.4) (2026-04-01)
|
|
42
|
+
|
|
43
|
+
### [0.0.3](https://github.com/iamandersonp/prettier-staged/compare/v0.0.2...v0.0.3) (2026-04-01)
|
|
37
44
|
|
|
38
45
|
### Bug Fixes
|
|
39
46
|
|
|
40
|
-
|
|
47
|
+
- :rocket: add preetier dependency ([c892b0d](https://github.com/iamandersonp/prettier-staged/commits/c892b0dc699bc07411907d70386114f84ecf3c3c))
|
|
41
48
|
|
|
42
|
-
### [0.0.2](https://github.com/iamandersonp/
|
|
49
|
+
### [0.0.2](https://github.com/iamandersonp/prettier-staged/compare/v0.0.1...v0.0.2) (2026-04-01)
|
|
43
50
|
|
|
44
51
|
### 0.0.1 (2026-04-01)
|
|
45
52
|
|
|
46
|
-
|
|
47
53
|
### Features
|
|
48
54
|
|
|
49
|
-
|
|
55
|
+
- :tada: initial versión ([d9e520f](https://github.com/iamandersonp/prettier-staged/commits/d9e520f49456489c396a61d87b56cd3c90c22b7b))
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @iamandersonp/prettier-staged
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Configurable utility to auto-format staged files using Prettier with customizable file extensions and hooks directory
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -24,23 +24,63 @@ Create a command on your package.json
|
|
|
24
24
|
"prettier-staged": "prettier-staged",
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
## File Extensions Configuration
|
|
28
|
+
|
|
29
|
+
By default, prettier-staged formats these file types: `html`, `ts`, `scss`, `css`, `json`, `js`
|
|
30
|
+
|
|
31
|
+
You can customize which file extensions to format by creating a `.env` file in your project root:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# .env
|
|
35
|
+
EXTENSIONS=js,jsx,ts,tsx,css,scss
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Examples of custom configurations:**
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# React project
|
|
42
|
+
EXTENSIONS=js,jsx,ts,tsx,css,scss
|
|
43
|
+
|
|
44
|
+
# Vue project
|
|
45
|
+
EXTENSIONS=vue,js,ts,css,scss
|
|
46
|
+
|
|
47
|
+
# TypeScript-only project
|
|
48
|
+
EXTENSIONS=ts,tsx
|
|
49
|
+
|
|
50
|
+
# Full-stack project
|
|
51
|
+
EXTENSIONS=html,js,jsx,ts,tsx,vue,css,scss,less,json
|
|
52
|
+
|
|
53
|
+
# With quotes and spaces (automatically cleaned)
|
|
54
|
+
EXTENSIONS="js, jsx, ts, tsx"
|
|
55
|
+
EXTENSIONS='vue, css, scss'
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
If no `.env` file exists or `EXTENSIONS` is not specified, the default extensions will be used.
|
|
59
|
+
|
|
27
60
|
## Automatic Hook Installation
|
|
28
61
|
|
|
29
62
|
When installed as a dependency (not during local development), prettier-staged automatically copies a pre-commit hook to your project's hooks directory. This provides a ready-to-use solution for formatting staged files.
|
|
30
63
|
|
|
31
64
|
### Configuration
|
|
32
65
|
|
|
33
|
-
You can configure the hooks directory using an optional `.env` file in your project root:
|
|
66
|
+
You can configure the hooks directory and file extensions using an optional `.env` file in your project root:
|
|
34
67
|
|
|
35
68
|
```bash
|
|
36
69
|
# .env (optional)
|
|
37
|
-
HOOKS_DIR=.git-hooks
|
|
38
|
-
#
|
|
70
|
+
HOOKS_DIR=.git-hooks # Default hooks directory
|
|
71
|
+
EXTENSIONS=html,ts,scss,css,json,js # Default file extensions
|
|
72
|
+
|
|
73
|
+
# Customize as needed:
|
|
39
74
|
HOOKS_DIR=custom-hooks
|
|
40
|
-
HOOKS_DIR="my hooks"
|
|
75
|
+
HOOKS_DIR="my hooks" # With spaces (quotes optional)
|
|
76
|
+
EXTENSIONS=js,jsx,ts,tsx # Custom file extensions
|
|
77
|
+
EXTENSIONS="vue,svelte,astro" # Framework-specific files
|
|
41
78
|
```
|
|
42
79
|
|
|
43
|
-
If no `.env` file exists, the default
|
|
80
|
+
If no `.env` file exists, the default values will be used:
|
|
81
|
+
|
|
82
|
+
- **HOOKS_DIR**: `.git-hooks`
|
|
83
|
+
- **EXTENSIONS**: `html,ts,scss,css,json,js`
|
|
44
84
|
|
|
45
85
|
#### Setting up your .env file
|
|
46
86
|
|
|
@@ -50,12 +90,19 @@ If no `.env` file exists, the default directory `.git-hooks` will be used.
|
|
|
50
90
|
cp .env.example .env
|
|
51
91
|
```
|
|
52
92
|
|
|
53
|
-
2. Edit `.env` to customize your
|
|
93
|
+
2. Edit `.env` to customize your configuration (optional):
|
|
54
94
|
|
|
55
95
|
```bash
|
|
96
|
+
# Hooks directory
|
|
56
97
|
HOOKS_DIR=.git-hooks # Use default
|
|
57
98
|
# or
|
|
58
99
|
HOOKS_DIR=git-hooks # Custom directory
|
|
100
|
+
|
|
101
|
+
# File extensions to format
|
|
102
|
+
EXTENSIONS=html,ts,scss,css,json,js # Use default
|
|
103
|
+
# or
|
|
104
|
+
EXTENSIONS=js,jsx,ts,tsx # JavaScript/TypeScript only
|
|
105
|
+
EXTENSIONS=vue,svelte,astro # Framework-specific
|
|
59
106
|
```
|
|
60
107
|
|
|
61
108
|
### What gets installed
|
|
@@ -93,14 +140,25 @@ git config core.hooksPath your-custom-directory
|
|
|
93
140
|
|
|
94
141
|
```bash
|
|
95
142
|
# All these formats are valid:
|
|
143
|
+
|
|
144
|
+
# Hooks directory:
|
|
96
145
|
HOOKS_DIR=.git-hooks # Basic format
|
|
97
146
|
HOOKS_DIR=".git-hooks" # With double quotes
|
|
98
147
|
HOOKS_DIR='.git-hooks' # With single quotes
|
|
99
148
|
HOOKS_DIR=custom-hooks-dir # Custom directory name
|
|
100
149
|
HOOKS_DIR="hooks with spaces" # Directories with spaces
|
|
150
|
+
|
|
151
|
+
# File extensions:
|
|
152
|
+
EXTENSIONS=html,ts,scss,css,json,js # Basic format
|
|
153
|
+
EXTENSIONS="js,jsx,ts,tsx" # With double quotes
|
|
154
|
+
EXTENSIONS='vue,svelte,astro' # With single quotes
|
|
155
|
+
EXTENSIONS=js, ts, css, scss # With spaces (auto-trimmed)
|
|
101
156
|
```
|
|
102
157
|
|
|
103
|
-
**Note**: If the `.env` file doesn't exist or has errors, the default
|
|
158
|
+
**Note**: If the `.env` file doesn't exist or has errors, the default values are used automatically:
|
|
159
|
+
|
|
160
|
+
- **HOOKS_DIR**: `.git-hooks`
|
|
161
|
+
- **EXTENSIONS**: `html,ts,scss,css,json,js`
|
|
104
162
|
|
|
105
163
|
### Custom implementation
|
|
106
164
|
|
|
@@ -108,16 +166,37 @@ If you prefer a custom implementation, you can create your own pre-commit hook u
|
|
|
108
166
|
|
|
109
167
|
```bash
|
|
110
168
|
#!/bin/sh
|
|
111
|
-
#
|
|
169
|
+
# Función para leer extensiones desde .env
|
|
170
|
+
get_extensions_from_env() {
|
|
171
|
+
local env_file=".env"
|
|
172
|
+
local default_extensions="html|ts|scss|css|json|js"
|
|
173
|
+
|
|
174
|
+
if [ ! -f "$env_file" ]; then
|
|
175
|
+
echo "$default_extensions"
|
|
176
|
+
return
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
# Buscar EXTENSIONS en .env
|
|
180
|
+
local extensions=$(grep "^EXTENSIONS=" "$env_file" 2>/dev/null | cut -d'=' -f2- | tr -d '"' | tr -d "'")
|
|
181
|
+
|
|
182
|
+
if [ -n "$extensions" ]; then
|
|
183
|
+
# Convertir comas a | para el regex
|
|
184
|
+
echo "$extensions" | sed 's/,/|/g' | sed 's/ //g'
|
|
185
|
+
else
|
|
186
|
+
echo "$default_extensions"
|
|
187
|
+
fi
|
|
188
|
+
}
|
|
112
189
|
|
|
113
190
|
if git ls-files -u | grep -q .; then
|
|
114
|
-
echo "⚠️ Merge in progress. Skipping Prettier to avoid issues."
|
|
191
|
+
echo "⚠️ Merge in progress. Skipping Prettier to avoid issues."
|
|
115
192
|
exit 0
|
|
116
193
|
fi
|
|
117
194
|
|
|
118
195
|
npm run prettier-staged
|
|
119
196
|
|
|
120
|
-
|
|
197
|
+
# Obtener extensiones desde .env y construir patrón dinámico
|
|
198
|
+
EXTENSIONS_PATTERN=$(get_extensions_from_env)
|
|
199
|
+
STAGED_FILES=$(git diff --name-only --cached --diff-filter=ACM | grep -E "\.($EXTENSIONS_PATTERN)$")
|
|
121
200
|
|
|
122
201
|
if [ -n "$STAGED_FILES" ]; then
|
|
123
202
|
echo "$STAGED_FILES" | xargs git add
|
|
@@ -132,10 +211,16 @@ fi
|
|
|
132
211
|
npm install -D @iamandersonp/prettier-staged
|
|
133
212
|
```
|
|
134
213
|
|
|
135
|
-
2. **Optional: Configure
|
|
214
|
+
2. **Optional: Configure your preferences**:
|
|
136
215
|
|
|
137
216
|
```bash
|
|
217
|
+
# Create .env file with custom configuration
|
|
138
218
|
echo "HOOKS_DIR=.git-hooks" > .env
|
|
219
|
+
echo "EXTENSIONS=html,ts,scss,css,json,js" >> .env
|
|
220
|
+
|
|
221
|
+
# Or copy and edit the example
|
|
222
|
+
cp .env.example .env
|
|
223
|
+
# Edit .env to customize HOOKS_DIR and EXTENSIONS
|
|
139
224
|
```
|
|
140
225
|
|
|
141
226
|
3. **The hook is automatically set up!** No additional configuration needed.
|
|
@@ -172,5 +257,11 @@ Current test coverage: **>95%** including:
|
|
|
172
257
|
- ✅ No files to format scenarios
|
|
173
258
|
- ✅ Error handling (Prettier not found, syntax errors, general errors)
|
|
174
259
|
- ✅ Edge cases (files with spaces, whitespace trimming, all supported extensions)
|
|
260
|
+
- ✅ Extensions configuration from `.env` file (custom extensions, fallback to defaults, error handling)
|
|
261
|
+
- ✅ Hooks directory configuration from `.env` file
|
|
175
262
|
|
|
176
263
|
The tests use mocks to simulate Git commands and Prettier execution without running actual commands, making tests fast and reliable.
|
|
264
|
+
|
|
265
|
+
## Changelog
|
|
266
|
+
|
|
267
|
+
All history of changes are located on [CHANGELOG.md](./CHANGELOG.md).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iamandersonp/prettier-staged",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"main": "src/index.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"prettier-staged": "src/index.js"
|
|
@@ -21,7 +21,11 @@
|
|
|
21
21
|
"prettier",
|
|
22
22
|
"staged",
|
|
23
23
|
"git",
|
|
24
|
-
"hooks"
|
|
24
|
+
"hooks",
|
|
25
|
+
"formatting",
|
|
26
|
+
"configurable",
|
|
27
|
+
"extensions",
|
|
28
|
+
"pre-commit"
|
|
25
29
|
],
|
|
26
30
|
"author": "Anderson Penaloza <info@iamanderson.dev>",
|
|
27
31
|
"repository": {
|
|
@@ -30,7 +34,7 @@
|
|
|
30
34
|
},
|
|
31
35
|
"homepage": "https://github.com/iamandersonp/prettier-staged.git",
|
|
32
36
|
"license": "GPL-3.0-only",
|
|
33
|
-
"description": "
|
|
37
|
+
"description": "Configurable utility to auto-format staged files using Prettier with customizable file extensions and hooks directory",
|
|
34
38
|
"readme": "README.md",
|
|
35
39
|
"dependencies": {
|
|
36
40
|
"prettier": "^3.8.1"
|
package/src/index.js
CHANGED
|
@@ -1,8 +1,63 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { execSync } = require('node:child_process');
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const path = require('node:path');
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
// Constante para las extensiones por defecto
|
|
8
|
+
const DEFAULT_EXTENSIONS = ['html', 'ts', 'scss', 'css', 'json', 'js'];
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Lee el archivo .env para obtener EXTENSIONS, retorna el valor por defecto si no existe
|
|
12
|
+
*/
|
|
13
|
+
function getExtensionsFromEnv() {
|
|
14
|
+
try {
|
|
15
|
+
const envPath = path.join(process.cwd(), '.env');
|
|
16
|
+
|
|
17
|
+
if (!fs.existsSync(envPath)) {
|
|
18
|
+
return DEFAULT_EXTENSIONS;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const envContent = fs.readFileSync(envPath, 'utf8');
|
|
22
|
+
const lines = envContent.split('\n');
|
|
23
|
+
|
|
24
|
+
for (const line of lines) {
|
|
25
|
+
const trimmedLine = line.trim();
|
|
26
|
+
if (trimmedLine.startsWith('EXTENSIONS=')) {
|
|
27
|
+
const value = trimmedLine.substring('EXTENSIONS='.length).trim();
|
|
28
|
+
// Remover comillas si existen (simples o dobles)
|
|
29
|
+
let cleanValue = value
|
|
30
|
+
.replace(/^['"]/, '') // Remover comilla de inicio
|
|
31
|
+
.replace(/['"]/, ''); // Remover comilla de final
|
|
32
|
+
|
|
33
|
+
if (cleanValue) {
|
|
34
|
+
// Convertir string separado por comas a array
|
|
35
|
+
return cleanValue
|
|
36
|
+
.split(',')
|
|
37
|
+
.map((ext) => ext.trim())
|
|
38
|
+
.filter(Boolean);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return DEFAULT_EXTENSIONS;
|
|
44
|
+
} catch (error) {
|
|
45
|
+
// Si hay cualquier error leyendo el archivo, usar valor por defecto
|
|
46
|
+
console.warn('Warning: Could not read .env file, using default EXTENSIONS:', error.message);
|
|
47
|
+
return DEFAULT_EXTENSIONS;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Crear regex para extensiones basado en la configuración
|
|
53
|
+
*/
|
|
54
|
+
function createExtensionsRegex(extensionsArray) {
|
|
55
|
+
const pattern = String.raw`\.(${extensionsArray.join('|')})$`;
|
|
56
|
+
return new RegExp(pattern);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Constante para las extensiones (lee desde .env o usa valor por defecto)
|
|
60
|
+
const extensions = createExtensionsRegex(getExtensionsFromEnv());
|
|
6
61
|
|
|
7
62
|
function runPrettierStaged() {
|
|
8
63
|
try {
|
|
@@ -41,4 +96,9 @@ if (require.main === module) {
|
|
|
41
96
|
runPrettierStaged();
|
|
42
97
|
}
|
|
43
98
|
|
|
44
|
-
module.exports = {
|
|
99
|
+
module.exports = {
|
|
100
|
+
runPrettierStaged,
|
|
101
|
+
getExtensionsFromEnv,
|
|
102
|
+
createExtensionsRegex,
|
|
103
|
+
DEFAULT_EXTENSIONS
|
|
104
|
+
};
|
package/tests/index.test.js
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
const { execSync } = require('node:child_process');
|
|
2
|
+
const fs = require('node:fs');
|
|
2
3
|
|
|
3
|
-
// Mock
|
|
4
|
+
// Mock de child_process
|
|
4
5
|
jest.mock('node:child_process', () => ({
|
|
5
6
|
execSync: jest.fn()
|
|
6
7
|
}));
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
// Mock de node:fs
|
|
10
|
+
jest.mock('node:fs');
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
runPrettierStaged,
|
|
14
|
+
getExtensionsFromEnv,
|
|
15
|
+
createExtensionsRegex,
|
|
16
|
+
DEFAULT_EXTENSIONS
|
|
17
|
+
} = require('../src/index.js');
|
|
9
18
|
|
|
10
19
|
describe('prettier-staged CLI', () => {
|
|
11
20
|
let consoleSpy, errorSpy, exitSpy;
|
|
@@ -230,4 +239,126 @@ describe('prettier-staged CLI', () => {
|
|
|
230
239
|
});
|
|
231
240
|
});
|
|
232
241
|
});
|
|
242
|
+
|
|
243
|
+
describe('getExtensionsFromEnv', () => {
|
|
244
|
+
beforeEach(() => {
|
|
245
|
+
// Reset fs mocks
|
|
246
|
+
fs.existsSync = jest.fn();
|
|
247
|
+
fs.readFileSync = jest.fn();
|
|
248
|
+
// Reset process.cwd
|
|
249
|
+
jest.spyOn(process, 'cwd').mockReturnValue('/test/project');
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
afterEach(() => {
|
|
253
|
+
process.cwd.mockRestore();
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it('should return default extensions when .env file does not exist', () => {
|
|
257
|
+
fs.existsSync.mockReturnValue(false);
|
|
258
|
+
|
|
259
|
+
const result = getExtensionsFromEnv();
|
|
260
|
+
|
|
261
|
+
expect(result).toEqual(DEFAULT_EXTENSIONS);
|
|
262
|
+
expect(fs.existsSync).toHaveBeenCalledWith('/test/project/.env');
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it('should return extensions from .env file when EXTENSIONS is set', () => {
|
|
266
|
+
fs.existsSync.mockReturnValue(true);
|
|
267
|
+
fs.readFileSync.mockReturnValue('NODE_ENV=test\nEXTENSIONS=js,jsx,ts,tsx\nOTHER=value');
|
|
268
|
+
|
|
269
|
+
const result = getExtensionsFromEnv();
|
|
270
|
+
|
|
271
|
+
expect(result).toEqual(['js', 'jsx', 'ts', 'tsx']);
|
|
272
|
+
expect(fs.readFileSync).toHaveBeenCalledWith('/test/project/.env', 'utf8');
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it('should return default extensions when .env exists but EXTENSIONS is not set', () => {
|
|
276
|
+
fs.existsSync.mockReturnValue(true);
|
|
277
|
+
fs.readFileSync.mockReturnValue('NODE_ENV=test\nOTHER=value');
|
|
278
|
+
|
|
279
|
+
const result = getExtensionsFromEnv();
|
|
280
|
+
|
|
281
|
+
expect(result).toEqual(DEFAULT_EXTENSIONS);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it('should remove quotes and trim spaces from EXTENSIONS value', () => {
|
|
285
|
+
fs.existsSync.mockReturnValue(true);
|
|
286
|
+
fs.readFileSync.mockReturnValue('EXTENSIONS="html, ts , css, json"');
|
|
287
|
+
|
|
288
|
+
const result = getExtensionsFromEnv();
|
|
289
|
+
|
|
290
|
+
expect(result).toEqual(['html', 'ts', 'css', 'json']);
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('should remove single quotes from EXTENSIONS value', () => {
|
|
294
|
+
fs.existsSync.mockReturnValue(true);
|
|
295
|
+
fs.readFileSync.mockReturnValue("EXTENSIONS='vue,svelte,astro'");
|
|
296
|
+
|
|
297
|
+
const result = getExtensionsFromEnv();
|
|
298
|
+
|
|
299
|
+
expect(result).toEqual(['vue', 'svelte', 'astro']);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
it('should handle file read errors gracefully', () => {
|
|
303
|
+
fs.existsSync.mockReturnValue(true);
|
|
304
|
+
fs.readFileSync.mockImplementation(() => {
|
|
305
|
+
throw new Error('Permission denied');
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
const result = getExtensionsFromEnv();
|
|
309
|
+
|
|
310
|
+
expect(result).toEqual(DEFAULT_EXTENSIONS);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it('should return default extensions when EXTENSIONS is empty', () => {
|
|
314
|
+
fs.existsSync.mockReturnValue(true);
|
|
315
|
+
fs.readFileSync.mockReturnValue('EXTENSIONS=\nOTHER=value');
|
|
316
|
+
|
|
317
|
+
const result = getExtensionsFromEnv();
|
|
318
|
+
|
|
319
|
+
expect(result).toEqual(DEFAULT_EXTENSIONS);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
it('should filter out empty extensions after split', () => {
|
|
323
|
+
fs.existsSync.mockReturnValue(true);
|
|
324
|
+
fs.readFileSync.mockReturnValue('EXTENSIONS=js,,ts, ,jsx,');
|
|
325
|
+
|
|
326
|
+
const result = getExtensionsFromEnv();
|
|
327
|
+
|
|
328
|
+
expect(result).toEqual(['js', 'ts', 'jsx']);
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
describe('createExtensionsRegex', () => {
|
|
333
|
+
it('should create regex for single extension', () => {
|
|
334
|
+
const result = createExtensionsRegex(['js']);
|
|
335
|
+
|
|
336
|
+
expect(result).toEqual(/\.(js)$/);
|
|
337
|
+
expect(result.test('app.js')).toBe(true);
|
|
338
|
+
expect(result.test('app.ts')).toBe(false);
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it('should create regex for multiple extensions', () => {
|
|
342
|
+
const result = createExtensionsRegex(['js', 'ts', 'jsx']);
|
|
343
|
+
|
|
344
|
+
expect(result).toEqual(/\.(js|ts|jsx)$/);
|
|
345
|
+
expect(result.test('app.js')).toBe(true);
|
|
346
|
+
expect(result.test('component.ts')).toBe(true);
|
|
347
|
+
expect(result.test('Component.jsx')).toBe(true);
|
|
348
|
+
expect(result.test('style.css')).toBe(false);
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
it('should create regex for default extensions', () => {
|
|
352
|
+
const result = createExtensionsRegex(DEFAULT_EXTENSIONS);
|
|
353
|
+
|
|
354
|
+
expect(result).toEqual(/\.(html|ts|scss|css|json|js)$/);
|
|
355
|
+
expect(result.test('index.html')).toBe(true);
|
|
356
|
+
expect(result.test('app.ts')).toBe(true);
|
|
357
|
+
expect(result.test('style.scss')).toBe(true);
|
|
358
|
+
expect(result.test('reset.css')).toBe(true);
|
|
359
|
+
expect(result.test('package.json')).toBe(true);
|
|
360
|
+
expect(result.test('script.js')).toBe(true);
|
|
361
|
+
expect(result.test('readme.md')).toBe(false);
|
|
362
|
+
});
|
|
363
|
+
});
|
|
233
364
|
});
|