js-style-kit 0.6.0 → 0.7.0
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/README.md +5 -0
- package/dist/index.d.ts +11 -5
- package/dist/index.js +48 -77
- package/dist/index.js.map +1 -1
- package/package.json +36 -33
- package/src/eslint/base/README.md +186 -0
- package/src/eslint/base/config.ts +37 -0
- package/src/eslint/base/rules.ts +444 -0
- package/src/eslint/base/types.ts +20 -0
- package/src/eslint/constants.ts +52 -0
- package/src/eslint/convex/README.md +30 -0
- package/src/eslint/convex/config.ts +34 -0
- package/src/eslint/convex/rules.ts +8 -0
- package/src/eslint/convex/types.ts +8 -0
- package/src/eslint/ignores.ts +31 -0
- package/src/eslint/import/README.md +397 -0
- package/src/eslint/import/config.ts +48 -0
- package/src/eslint/import/rules.ts +81 -0
- package/src/eslint/index.ts +259 -0
- package/src/eslint/jsdoc/README.md +399 -0
- package/src/eslint/jsdoc/config.ts +29 -0
- package/src/eslint/jsdoc/rules.ts +81 -0
- package/src/eslint/jsdoc/types.ts +56 -0
- package/src/eslint/nextjs/config.ts +25 -0
- package/src/eslint/nextjs/rules.ts +25 -0
- package/src/eslint/nextjs/types.ts +27 -0
- package/src/eslint/perfectionist/README.md +454 -0
- package/src/eslint/perfectionist/config.ts +25 -0
- package/src/eslint/perfectionist/rules.ts +39 -0
- package/src/eslint/prefer-arrow-function/config.ts +33 -0
- package/src/eslint/prefer-arrow-function/types.ts +13 -0
- package/src/eslint/process-custom-rules.ts +72 -0
- package/src/eslint/query/README.md +254 -0
- package/src/eslint/query/config.ts +27 -0
- package/src/eslint/query/rules.ts +11 -0
- package/src/eslint/query/types.ts +11 -0
- package/src/eslint/react/README.md +416 -0
- package/src/eslint/react/config.ts +65 -0
- package/src/eslint/react/rules.ts +188 -0
- package/src/eslint/react/types.ts +26 -0
- package/src/eslint/react-refresh/config.ts +28 -0
- package/src/eslint/react-refresh/rules.ts +48 -0
- package/src/eslint/storybook/README.md +424 -0
- package/src/eslint/storybook/config.ts +57 -0
- package/src/eslint/testing/README.md +436 -0
- package/src/eslint/testing/config.ts +90 -0
- package/src/eslint/testing/jest-rules.ts +47 -0
- package/src/eslint/testing/vitest-rules.ts +42 -0
- package/src/eslint/turbo/README.md +380 -0
- package/src/eslint/turbo/config.ts +26 -0
- package/src/eslint/turbo/types.ts +7 -0
- package/src/eslint/types.ts +29 -0
- package/src/eslint/typescript/README.md +229 -0
- package/src/eslint/typescript/config.ts +48 -0
- package/src/eslint/typescript/rules.ts +137 -0
- package/src/eslint/typescript/types.ts +35 -0
- package/src/eslint/unicorn/README.md +497 -0
- package/src/eslint/unicorn/config.ts +36 -0
- package/src/eslint/unicorn/rules.ts +86 -0
- package/src/index.ts +3 -0
- package/src/modules.d.ts +5 -0
- package/src/prettier/README.md +413 -0
- package/src/prettier/index.ts +110 -0
- package/src/utils/is-type.ts +60 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { EslintRuleConfig, FilenameCase } from "../types.js";
|
|
2
|
+
|
|
3
|
+
type UnicornRules = Record<`unicorn/${string}`, EslintRuleConfig>;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generate Unicorn ESLint rules with configurable filename case.
|
|
7
|
+
*
|
|
8
|
+
* @param filenameCase - The filename case to enforce. Defaults to "kebabCase".
|
|
9
|
+
* @returns Unicorn ESLint rules configuration.
|
|
10
|
+
*/
|
|
11
|
+
export const rules = (
|
|
12
|
+
filenameCase: FilenameCase = "kebabCase",
|
|
13
|
+
): UnicornRules => ({
|
|
14
|
+
/**
|
|
15
|
+
* Enforce better string content.
|
|
16
|
+
*
|
|
17
|
+
* 🔧 Fixable - https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/better-regex.md
|
|
18
|
+
*/
|
|
19
|
+
"unicorn/better-regex": "warn",
|
|
20
|
+
/**
|
|
21
|
+
* Enforce passing a message value when creating a built-in error.
|
|
22
|
+
*
|
|
23
|
+
* 🚫 Not fixable - https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/error-message.md
|
|
24
|
+
*/
|
|
25
|
+
"unicorn/error-message": "warn",
|
|
26
|
+
/**
|
|
27
|
+
* Require consistent filename case for all linted files.
|
|
28
|
+
*
|
|
29
|
+
* 🚫 Not fixable - https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/filename-case.md
|
|
30
|
+
*/
|
|
31
|
+
"unicorn/filename-case": [
|
|
32
|
+
"warn",
|
|
33
|
+
{
|
|
34
|
+
case: filenameCase,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
/**
|
|
38
|
+
* Enforce the use of new for all builtins, except String, Number, Boolean, Symbol and BigInt.
|
|
39
|
+
*
|
|
40
|
+
* 🔧 Fixable - https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/new-for-builtins.md
|
|
41
|
+
*/
|
|
42
|
+
"unicorn/new-for-builtins": "warn",
|
|
43
|
+
"unicorn/no-console-spaces": "warn",
|
|
44
|
+
/**
|
|
45
|
+
* Enforce using for-loop instead of while-loop.
|
|
46
|
+
*
|
|
47
|
+
* 🔧 Fixable - https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-for-loop.md
|
|
48
|
+
*/
|
|
49
|
+
"unicorn/no-for-loop": "warn",
|
|
50
|
+
/**
|
|
51
|
+
* Enforce the use of addEventListener and removeEventListener over on-functions.
|
|
52
|
+
*
|
|
53
|
+
* 🔧 Fixable - https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-add-event-listener.md
|
|
54
|
+
*/
|
|
55
|
+
"unicorn/prefer-add-event-listener": "warn",
|
|
56
|
+
/**
|
|
57
|
+
* Require using the `node:` protocol when importing Node.js built-in modules.
|
|
58
|
+
*
|
|
59
|
+
* 🔧 Fixable - https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-node-protocol.md
|
|
60
|
+
*/
|
|
61
|
+
"unicorn/prefer-node-protocol": "warn",
|
|
62
|
+
/**
|
|
63
|
+
* Prefer String#replaceAll() over String#replace() with a global regExp.
|
|
64
|
+
*
|
|
65
|
+
* 🔧 Fixable - https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-replace-all.md
|
|
66
|
+
*/
|
|
67
|
+
"unicorn/prefer-string-replace-all": "warn",
|
|
68
|
+
/**
|
|
69
|
+
* Enforce throwing TypeError in type checking conditions.
|
|
70
|
+
*
|
|
71
|
+
* 🔧 Fixable - https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-type-error.md
|
|
72
|
+
*/
|
|
73
|
+
"unicorn/prefer-type-error": "warn",
|
|
74
|
+
/**
|
|
75
|
+
* Enforce consistent brace style for case clauses.
|
|
76
|
+
*
|
|
77
|
+
* 🔧 Fixable - https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/switch-case-braces.md
|
|
78
|
+
*/
|
|
79
|
+
"unicorn/switch-case-braces": ["warn", "always"],
|
|
80
|
+
/**
|
|
81
|
+
* Enforce consistent case for text encoding identifiers.
|
|
82
|
+
*
|
|
83
|
+
* 🔧 Fixable - https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/text-encoding-identifier-case.md
|
|
84
|
+
*/
|
|
85
|
+
"unicorn/text-encoding-identifier-case": "warn",
|
|
86
|
+
});
|
package/src/index.ts
ADDED
package/src/modules.d.ts
ADDED
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
# Prettier Configuration
|
|
2
|
+
|
|
3
|
+
Opinionated Prettier configuration with powerful plugins for CSS ordering, JSON sorting, Tailwind class sorting, and more.
|
|
4
|
+
|
|
5
|
+
[← Back to main README](../../README.md)
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
The Prettier configuration includes:
|
|
10
|
+
|
|
11
|
+
- **Faster parser** - OXC parser for improved performance (optional)
|
|
12
|
+
- **CSS ordering** - Consistent property order
|
|
13
|
+
- **Curly braces** - Enforce braces for all control statements
|
|
14
|
+
- **JSON sorting** - Alphabetical key sorting
|
|
15
|
+
- **Package.json** - Consistent dependency ordering
|
|
16
|
+
- **Tailwind CSS** - Class name sorting (optional)
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
// @ts-check
|
|
22
|
+
import { prettierConfig } from "js-style-kit";
|
|
23
|
+
|
|
24
|
+
export default prettierConfig();
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Configuration Options
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
// @ts-check
|
|
31
|
+
import { prettierConfig } from "js-style-kit";
|
|
32
|
+
|
|
33
|
+
export default prettierConfig({
|
|
34
|
+
// Plugin options (all boolean or config object)
|
|
35
|
+
cssOrderPlugin: true, // Sort CSS properties
|
|
36
|
+
curlyPlugin: true, // Enforce curly braces
|
|
37
|
+
jsonSortPlugin: true, // Sort JSON keys
|
|
38
|
+
packageJsonPlugin: true, // Sort package.json
|
|
39
|
+
tailwindPlugin: false, // Tailwind class sorting
|
|
40
|
+
parser: "oxc", // "oxc" (faster) or "default"
|
|
41
|
+
|
|
42
|
+
// Standard Prettier options
|
|
43
|
+
printWidth: 80,
|
|
44
|
+
tabWidth: 2,
|
|
45
|
+
semi: true,
|
|
46
|
+
singleQuote: false,
|
|
47
|
+
trailingComma: "all",
|
|
48
|
+
// ... any Prettier option
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Parser Options
|
|
53
|
+
|
|
54
|
+
### OXC Parser (Default)
|
|
55
|
+
|
|
56
|
+
The **OXC parser** is a faster alternative to Prettier's default parser:
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
// @ts-check
|
|
60
|
+
export default prettierConfig({
|
|
61
|
+
parser: "oxc", // Default - faster performance
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Benefits:**
|
|
66
|
+
|
|
67
|
+
- ⚡ Significantly faster than default parser
|
|
68
|
+
- ✅ 100% compatible with Prettier
|
|
69
|
+
- ✅ Written in Rust for performance
|
|
70
|
+
|
|
71
|
+
### Default Parser
|
|
72
|
+
|
|
73
|
+
Use Prettier's standard parser:
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
// @ts-check
|
|
77
|
+
export default prettierConfig({
|
|
78
|
+
parser: "default", // Standard Prettier parser
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Plugin Features
|
|
83
|
+
|
|
84
|
+
### CSS Property Ordering
|
|
85
|
+
|
|
86
|
+
**Enabled by default** - Sorts CSS properties in a consistent order:
|
|
87
|
+
|
|
88
|
+
```css
|
|
89
|
+
/* ✅ Good - properties sorted */
|
|
90
|
+
.button {
|
|
91
|
+
display: flex;
|
|
92
|
+
align-items: center;
|
|
93
|
+
border-radius: 4px;
|
|
94
|
+
background-color: blue;
|
|
95
|
+
padding: 1rem;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Before formatting - unsorted */
|
|
99
|
+
.button {
|
|
100
|
+
display: flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
border-radius: 4px;
|
|
103
|
+
background-color: blue;
|
|
104
|
+
padding: 1rem;
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Disable:
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
cssOrderPlugin: false;
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Curly Braces Enforcement
|
|
115
|
+
|
|
116
|
+
**Enabled by default** - Enforces curly braces for all control statements:
|
|
117
|
+
|
|
118
|
+
```js
|
|
119
|
+
// ✅ Good - always has braces
|
|
120
|
+
if (condition) {
|
|
121
|
+
doSomething();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
for (const item of items) {
|
|
125
|
+
process(item);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Before formatting - missing braces
|
|
129
|
+
if (condition) doSomething();
|
|
130
|
+
for (const item of items) process(item);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
This is equivalent to ESLint's `curly: "all"` rule but applied at the formatting level.
|
|
134
|
+
|
|
135
|
+
Disable:
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
curlyPlugin: false;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### JSON Sorting
|
|
142
|
+
|
|
143
|
+
**Enabled by default** - Sorts JSON object keys alphabetically:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
// ✅ Good - keys sorted
|
|
147
|
+
{
|
|
148
|
+
"apiUrl": "https://api.example.com",
|
|
149
|
+
"environment": "production",
|
|
150
|
+
"features": {
|
|
151
|
+
"analytics": true,
|
|
152
|
+
"darkMode": false
|
|
153
|
+
},
|
|
154
|
+
"timeout": 5000
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Before formatting - unsorted
|
|
158
|
+
{
|
|
159
|
+
"timeout": 5000,
|
|
160
|
+
"environment": "production",
|
|
161
|
+
"features": {
|
|
162
|
+
"darkMode": false,
|
|
163
|
+
"analytics": true
|
|
164
|
+
},
|
|
165
|
+
"apiUrl": "https://api.example.com"
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Recursive sorting** is enabled by default (sorts nested objects too).
|
|
170
|
+
|
|
171
|
+
#### Customize JSON Sorting
|
|
172
|
+
|
|
173
|
+
```js
|
|
174
|
+
jsonSortPlugin: {
|
|
175
|
+
jsonRecursiveSort: true, // Sort nested objects
|
|
176
|
+
jsonSortOrder: "{ ... }", // Custom sort order (advanced)
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
#### Disable
|
|
181
|
+
|
|
182
|
+
```js
|
|
183
|
+
jsonSortPlugin: false;
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Package.json Sorting
|
|
187
|
+
|
|
188
|
+
**Enabled by default** - Sorts package.json with smart dependency ordering:
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"name": "my-package",
|
|
193
|
+
"version": "1.0.0",
|
|
194
|
+
"description": "...",
|
|
195
|
+
"main": "index.js",
|
|
196
|
+
"scripts": { ... },
|
|
197
|
+
"dependencies": { ... },
|
|
198
|
+
"devDependencies": { ... }
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Follows npm/yarn conventions for field ordering.
|
|
203
|
+
|
|
204
|
+
Disable:
|
|
205
|
+
|
|
206
|
+
```js
|
|
207
|
+
packageJsonPlugin: false;
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Tailwind CSS Class Sorting
|
|
211
|
+
|
|
212
|
+
**Disabled by default** - Sorts Tailwind classes following official recommendations:
|
|
213
|
+
|
|
214
|
+
```jsx
|
|
215
|
+
// ✅ Good - classes sorted
|
|
216
|
+
<div className="flex items-center justify-between p-4 bg-blue-500 rounded-lg" />
|
|
217
|
+
|
|
218
|
+
// Before formatting - unsorted
|
|
219
|
+
<div className="p-4 bg-blue-500 flex rounded-lg items-center justify-between" />
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### Enable with path to global css file for Tailwind v4
|
|
223
|
+
|
|
224
|
+
```js
|
|
225
|
+
tailwindPlugin: "./src/index.css";
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
#### Specify Utility Functions
|
|
229
|
+
|
|
230
|
+
```js
|
|
231
|
+
tailwindPlugin: ["clsx", "cva", "cn", "myCustomUtil"];
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
#### Advanced Configuration
|
|
235
|
+
|
|
236
|
+
```js
|
|
237
|
+
tailwindPlugin: {
|
|
238
|
+
tailwindFunctions: ["clsx", "cva", "tw"],
|
|
239
|
+
tailwindAttributes: ["className", "class", "tw"],
|
|
240
|
+
tailwindStylesheet: "./styles/tailwind.css",
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Standard Prettier Options
|
|
245
|
+
|
|
246
|
+
All standard Prettier options are supported:
|
|
247
|
+
|
|
248
|
+
```js
|
|
249
|
+
export default prettierConfig({
|
|
250
|
+
// Plugins (documented above)
|
|
251
|
+
tailwindPlugin: true,
|
|
252
|
+
|
|
253
|
+
// Standard options
|
|
254
|
+
printWidth: 100, // Line length
|
|
255
|
+
tabWidth: 2, // Spaces per tab
|
|
256
|
+
useTabs: false, // Use spaces
|
|
257
|
+
semi: true, // Semicolons
|
|
258
|
+
singleQuote: false, // Double quotes
|
|
259
|
+
quoteProps: "as-needed", // Quote object properties
|
|
260
|
+
trailingComma: "all", // Trailing commas
|
|
261
|
+
bracketSpacing: true, // { foo: bar }
|
|
262
|
+
bracketSameLine: false, // JSX bracket on new line
|
|
263
|
+
arrowParens: "always", // (x) => x
|
|
264
|
+
endOfLine: "lf", // Unix line endings
|
|
265
|
+
proseWrap: "preserve", // Markdown wrapping
|
|
266
|
+
});
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Common Configurations
|
|
270
|
+
|
|
271
|
+
### Minimal (Disable Plugins)
|
|
272
|
+
|
|
273
|
+
```js
|
|
274
|
+
export default prettierConfig({
|
|
275
|
+
cssOrderPlugin: false,
|
|
276
|
+
curlyPlugin: false,
|
|
277
|
+
jsonSortPlugin: false,
|
|
278
|
+
packageJsonPlugin: false,
|
|
279
|
+
parser: "default",
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Tailwind Project
|
|
284
|
+
|
|
285
|
+
```js
|
|
286
|
+
export default prettierConfig({
|
|
287
|
+
tailwindPlugin: true,
|
|
288
|
+
printWidth: 100,
|
|
289
|
+
singleQuote: true,
|
|
290
|
+
});
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Library/Package
|
|
294
|
+
|
|
295
|
+
```js
|
|
296
|
+
export default prettierConfig({
|
|
297
|
+
packageJsonPlugin: true,
|
|
298
|
+
jsonSortPlugin: true,
|
|
299
|
+
singleQuote: true,
|
|
300
|
+
trailingComma: "es5",
|
|
301
|
+
});
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Next.js Project
|
|
305
|
+
|
|
306
|
+
```js
|
|
307
|
+
export default prettierConfig({
|
|
308
|
+
tailwindPlugin: {
|
|
309
|
+
tailwindFunctions: ["cn", "clsx"],
|
|
310
|
+
},
|
|
311
|
+
printWidth: 100,
|
|
312
|
+
});
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Package.json Scripts
|
|
316
|
+
|
|
317
|
+
Add these scripts to your package.json:
|
|
318
|
+
|
|
319
|
+
```json
|
|
320
|
+
{
|
|
321
|
+
"scripts": {
|
|
322
|
+
"format": "prettier --write .",
|
|
323
|
+
"format:check": "prettier --check ."
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Run `format:check` in CI to verify formatting.
|
|
329
|
+
|
|
330
|
+
## VS Code Integration
|
|
331
|
+
|
|
332
|
+
Add to `.vscode/settings.json`:
|
|
333
|
+
|
|
334
|
+
```json
|
|
335
|
+
{
|
|
336
|
+
"[javascript]": {
|
|
337
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
338
|
+
},
|
|
339
|
+
"[typescript]": {
|
|
340
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
341
|
+
},
|
|
342
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
343
|
+
"editor.formatOnSave": true
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Ignore Files
|
|
348
|
+
|
|
349
|
+
Create `.prettierignore`:
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
# Dependencies
|
|
353
|
+
node_modules
|
|
354
|
+
.pnpm-store
|
|
355
|
+
|
|
356
|
+
# Build outputs
|
|
357
|
+
dist
|
|
358
|
+
build
|
|
359
|
+
.next
|
|
360
|
+
out
|
|
361
|
+
|
|
362
|
+
# Misc
|
|
363
|
+
coverage
|
|
364
|
+
.cache
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## Plugin Documentation
|
|
368
|
+
|
|
369
|
+
Each plugin has additional options:
|
|
370
|
+
|
|
371
|
+
- **OXC Parser** - [Documentation](https://www.npmjs.com/package/@prettier/plugin-oxc)
|
|
372
|
+
- **CSS Order** - [Documentation](https://www.npmjs.com/package/prettier-plugin-css-order)
|
|
373
|
+
- **Curly** - [Documentation](https://www.npmjs.com/package/prettier-plugin-curly)
|
|
374
|
+
- **JSON Sort** - [Documentation](https://www.npmjs.com/package/prettier-plugin-sort-json)
|
|
375
|
+
- **Package.json** - [Documentation](https://www.npmjs.com/package/prettier-plugin-packagejson)
|
|
376
|
+
- **Tailwind** - [Documentation](https://github.com/tailwindlabs/prettier-plugin-tailwindcss)
|
|
377
|
+
|
|
378
|
+
## Troubleshooting
|
|
379
|
+
|
|
380
|
+
### Prettier not formatting
|
|
381
|
+
|
|
382
|
+
1. Check `.prettierignore` isn't excluding files
|
|
383
|
+
2. Verify VS Code is using the right formatter
|
|
384
|
+
3. Check for conflicting Prettier configs
|
|
385
|
+
|
|
386
|
+
### Tailwind classes not sorting
|
|
387
|
+
|
|
388
|
+
1. Ensure `tailwindPlugin` is set to your global css file path
|
|
389
|
+
2. Reload your IDE
|
|
390
|
+
3. Run the prettier CLI to see if there's an error
|
|
391
|
+
|
|
392
|
+
### OXC parser issues
|
|
393
|
+
|
|
394
|
+
Switch to default parser:
|
|
395
|
+
|
|
396
|
+
```js
|
|
397
|
+
parser: "default";
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### Plugin conflicts
|
|
401
|
+
|
|
402
|
+
Disable plugins one-by-one to identify conflicts:
|
|
403
|
+
|
|
404
|
+
```js
|
|
405
|
+
cssOrderPlugin: false,
|
|
406
|
+
curlyPlugin: false,
|
|
407
|
+
// etc.
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
## Learn More
|
|
411
|
+
|
|
412
|
+
- [Prettier Documentation](https://prettier.io/docs/en/)
|
|
413
|
+
- [Main README](../../README.md)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { Config as PrettierConfig } from "prettier";
|
|
2
|
+
import type { SortJsonOptions as SortJsonPluginOptions } from "prettier-plugin-sort-json";
|
|
3
|
+
import type { PluginOptions as TailwindPluginOptions } from "prettier-plugin-tailwindcss";
|
|
4
|
+
|
|
5
|
+
import { isObject, isString } from "../utils/is-type.js";
|
|
6
|
+
|
|
7
|
+
export interface PrettierConfigOptions extends PrettierConfig {
|
|
8
|
+
cssOrderPlugin?: boolean;
|
|
9
|
+
curlyPlugin?: boolean;
|
|
10
|
+
jsonSortPlugin?: boolean | SortJsonPluginOptions;
|
|
11
|
+
packageJsonPlugin?: boolean;
|
|
12
|
+
parser?: "default" | "oxc";
|
|
13
|
+
tailwindPlugin?: boolean | string | TailwindPluginOptions;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface PrettierConfigWithPlugins
|
|
17
|
+
extends PrettierConfig,
|
|
18
|
+
SortJsonPluginOptions,
|
|
19
|
+
TailwindPluginOptions {}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Creates a Prettier configuration object with optional Tailwind support
|
|
23
|
+
*
|
|
24
|
+
* @param options - Configuration options for Prettier
|
|
25
|
+
* @param options.cssOrderPlugin CSS order sorting support
|
|
26
|
+
* @param options.curlyPlugin Enforce curly braces for all control statements
|
|
27
|
+
* @param options.jsonSortPlugin JSON sorting support
|
|
28
|
+
* @param options.parser choose between default and oxc parser
|
|
29
|
+
* @param options.packageJsonPlugin Package.json sorting support
|
|
30
|
+
* @param options.tailwindPlugin Tailwind CSS formatting support
|
|
31
|
+
* @returns Prettier configuration object with:
|
|
32
|
+
* - Default Prettier configuration
|
|
33
|
+
* - Experimental ternaries enabled
|
|
34
|
+
* - OXC parser plugin
|
|
35
|
+
* - CSS order plugin
|
|
36
|
+
* - Curly braces plugin
|
|
37
|
+
* - JSON sorting plugin
|
|
38
|
+
* - Package.json sorting plugin
|
|
39
|
+
* - Optional Tailwind plugin and functions
|
|
40
|
+
*/
|
|
41
|
+
export const prettierConfig = (
|
|
42
|
+
options: PrettierConfigOptions = {},
|
|
43
|
+
): PrettierConfigWithPlugins => {
|
|
44
|
+
const {
|
|
45
|
+
cssOrderPlugin = true,
|
|
46
|
+
curlyPlugin = true,
|
|
47
|
+
jsonSortPlugin = true,
|
|
48
|
+
packageJsonPlugin = true,
|
|
49
|
+
parser = "oxc",
|
|
50
|
+
tailwindPlugin = false,
|
|
51
|
+
...rest
|
|
52
|
+
} = options;
|
|
53
|
+
|
|
54
|
+
const plugins: string[] = [];
|
|
55
|
+
const config: PrettierConfigWithPlugins = {
|
|
56
|
+
experimentalTernaries: true,
|
|
57
|
+
...rest,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
if (parser === "oxc") {
|
|
61
|
+
plugins.push("@prettier/plugin-oxc");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (cssOrderPlugin) {
|
|
65
|
+
plugins.push("prettier-plugin-css-order");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (curlyPlugin) {
|
|
69
|
+
plugins.push("prettier-plugin-curly");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (jsonSortPlugin) {
|
|
73
|
+
plugins.push("prettier-plugin-sort-json");
|
|
74
|
+
|
|
75
|
+
if (isObject(jsonSortPlugin)) {
|
|
76
|
+
Object.assign(config, jsonSortPlugin);
|
|
77
|
+
} else {
|
|
78
|
+
config.jsonRecursiveSort = true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (packageJsonPlugin) {
|
|
83
|
+
plugins.push("prettier-plugin-packagejson");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (tailwindPlugin) {
|
|
87
|
+
plugins.push("prettier-plugin-tailwindcss");
|
|
88
|
+
const defaultTailwindFunctions = ["clsx", "cva", "cn"];
|
|
89
|
+
|
|
90
|
+
if (isString(tailwindPlugin)) {
|
|
91
|
+
// then it's the path to the stylesheet
|
|
92
|
+
config.tailwindStylesheet = tailwindPlugin;
|
|
93
|
+
config.tailwindFunctions = defaultTailwindFunctions;
|
|
94
|
+
} else if (isObject(tailwindPlugin)) {
|
|
95
|
+
Object.assign(config, tailwindPlugin);
|
|
96
|
+
|
|
97
|
+
// Ensure defaultTailwindFunctions is applied if tailwindFunctions wasn't specified
|
|
98
|
+
if (!tailwindPlugin.tailwindFunctions) {
|
|
99
|
+
config.tailwindFunctions = defaultTailwindFunctions;
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
config.tailwindFunctions = defaultTailwindFunctions;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Set plugins after all configurations are done
|
|
107
|
+
config.plugins = plugins;
|
|
108
|
+
|
|
109
|
+
return config;
|
|
110
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type predicate for string values
|
|
3
|
+
*
|
|
4
|
+
* @param value - The value to check
|
|
5
|
+
* @returns True if the value is a string, false otherwise
|
|
6
|
+
*/
|
|
7
|
+
export const isString = (value: unknown): value is string => {
|
|
8
|
+
return typeof value === "string";
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Type predicate for number values
|
|
13
|
+
*
|
|
14
|
+
* @param value - The value to check
|
|
15
|
+
* @returns True if the value is a number and not NaN, false otherwise
|
|
16
|
+
*/
|
|
17
|
+
export const isNumber = (value: unknown): value is number => {
|
|
18
|
+
return typeof value === "number" && !Number.isNaN(value);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Type predicate for boolean values
|
|
23
|
+
*
|
|
24
|
+
* @param value - The value to check
|
|
25
|
+
* @returns True if the value is a boolean, false otherwise
|
|
26
|
+
*/
|
|
27
|
+
export const isBoolean = (value: unknown): value is boolean => {
|
|
28
|
+
return typeof value === "boolean";
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Type predicate for array values
|
|
33
|
+
*
|
|
34
|
+
* @param value - The value to check
|
|
35
|
+
* @returns True if the value is an array, false otherwise
|
|
36
|
+
*/
|
|
37
|
+
export const isArray = <T = unknown>(value: unknown): value is T[] => {
|
|
38
|
+
return Array.isArray(value);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Type predicate for object values (excluding null and arrays)
|
|
43
|
+
*
|
|
44
|
+
* @param value - The value to check
|
|
45
|
+
* @returns True if the value is an object (not null and not an array), false otherwise
|
|
46
|
+
*/
|
|
47
|
+
export const isObject = (value: unknown): value is Record<string, unknown> => {
|
|
48
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Type predicate for function values
|
|
53
|
+
*
|
|
54
|
+
* @param value - The value to check
|
|
55
|
+
* @returns True if the value is a function, false otherwise
|
|
56
|
+
*/
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
58
|
+
export const isFunction = (value: unknown): value is Function => {
|
|
59
|
+
return typeof value === "function";
|
|
60
|
+
};
|