js-style-kit 0.6.1 → 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.
Files changed (64) hide show
  1. package/README.md +5 -0
  2. package/dist/index.d.ts +11 -5
  3. package/dist/index.js +48 -7
  4. package/dist/index.js.map +1 -1
  5. package/package.json +8 -5
  6. package/src/eslint/base/README.md +186 -0
  7. package/src/eslint/base/config.ts +37 -0
  8. package/src/eslint/base/rules.ts +444 -0
  9. package/src/eslint/base/types.ts +20 -0
  10. package/src/eslint/constants.ts +52 -0
  11. package/src/eslint/convex/README.md +30 -0
  12. package/src/eslint/convex/config.ts +34 -0
  13. package/src/eslint/convex/rules.ts +8 -0
  14. package/src/eslint/convex/types.ts +8 -0
  15. package/src/eslint/ignores.ts +31 -0
  16. package/src/eslint/import/README.md +397 -0
  17. package/src/eslint/import/config.ts +48 -0
  18. package/src/eslint/import/rules.ts +81 -0
  19. package/src/eslint/index.ts +259 -0
  20. package/src/eslint/jsdoc/README.md +399 -0
  21. package/src/eslint/jsdoc/config.ts +29 -0
  22. package/src/eslint/jsdoc/rules.ts +81 -0
  23. package/src/eslint/jsdoc/types.ts +56 -0
  24. package/src/eslint/nextjs/config.ts +25 -0
  25. package/src/eslint/nextjs/rules.ts +25 -0
  26. package/src/eslint/nextjs/types.ts +27 -0
  27. package/src/eslint/perfectionist/README.md +454 -0
  28. package/src/eslint/perfectionist/config.ts +25 -0
  29. package/src/eslint/perfectionist/rules.ts +39 -0
  30. package/src/eslint/prefer-arrow-function/config.ts +33 -0
  31. package/src/eslint/prefer-arrow-function/types.ts +13 -0
  32. package/src/eslint/process-custom-rules.ts +72 -0
  33. package/src/eslint/query/README.md +254 -0
  34. package/src/eslint/query/config.ts +27 -0
  35. package/src/eslint/query/rules.ts +11 -0
  36. package/src/eslint/query/types.ts +11 -0
  37. package/src/eslint/react/README.md +416 -0
  38. package/src/eslint/react/config.ts +65 -0
  39. package/src/eslint/react/rules.ts +188 -0
  40. package/src/eslint/react/types.ts +26 -0
  41. package/src/eslint/react-refresh/config.ts +28 -0
  42. package/src/eslint/react-refresh/rules.ts +48 -0
  43. package/src/eslint/storybook/README.md +424 -0
  44. package/src/eslint/storybook/config.ts +57 -0
  45. package/src/eslint/testing/README.md +436 -0
  46. package/src/eslint/testing/config.ts +90 -0
  47. package/src/eslint/testing/jest-rules.ts +47 -0
  48. package/src/eslint/testing/vitest-rules.ts +42 -0
  49. package/src/eslint/turbo/README.md +380 -0
  50. package/src/eslint/turbo/config.ts +26 -0
  51. package/src/eslint/turbo/types.ts +7 -0
  52. package/src/eslint/types.ts +29 -0
  53. package/src/eslint/typescript/README.md +229 -0
  54. package/src/eslint/typescript/config.ts +48 -0
  55. package/src/eslint/typescript/rules.ts +137 -0
  56. package/src/eslint/typescript/types.ts +35 -0
  57. package/src/eslint/unicorn/README.md +497 -0
  58. package/src/eslint/unicorn/config.ts +36 -0
  59. package/src/eslint/unicorn/rules.ts +86 -0
  60. package/src/index.ts +3 -0
  61. package/src/modules.d.ts +5 -0
  62. package/src/prettier/README.md +413 -0
  63. package/src/prettier/index.ts +110 -0
  64. 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
@@ -0,0 +1,3 @@
1
+ export * from "./eslint/index.js";
2
+ export type * from "./eslint/types.js";
3
+ export * from "./prettier/index.js";
@@ -0,0 +1,5 @@
1
+ declare module "eslint-plugin-import" {}
2
+
3
+ declare module "eslint-plugin-react-hooks" {}
4
+
5
+ declare module "eslint-plugin-react-compiler" {}
@@ -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
+ };