@fabdeh/eslint-config 0.5.0 → 0.6.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/dist/index.d.mts CHANGED
@@ -2,6 +2,7 @@ import { ConfigArray, ConfigWithExtends } from 'typescript-eslint';
2
2
  import { StylisticCustomizeOptions } from '@stylistic/eslint-plugin';
3
3
  import { TSESLint } from '@typescript-eslint/utils';
4
4
  import { FlatGitignoreOptions } from 'eslint-config-flat-gitignore';
5
+ import { Attributes, Callees, Variables, Tags } from 'eslint-plugin-better-tailwindcss/api/types';
5
6
 
6
7
  /**
7
8
  * Vendor types from Prettier so we don't rely on the dependency.
@@ -240,6 +241,18 @@ interface AngularOptions {
240
241
  * @default true
241
242
  */
242
243
  preferOnPushOnly?: boolean;
244
+ /**
245
+ * Disallow using code which is marked as experimental.
246
+ *
247
+ * @default true
248
+ */
249
+ banExperimentalApi?: boolean;
250
+ /**
251
+ * Disallow using code which is marked as developer preview.
252
+ *
253
+ * @default true
254
+ */
255
+ banDeveloperPreviewApi?: boolean;
243
256
  }
244
257
  /**
245
258
  * Interface representing configuration options for enforcing NgRx operators rules.
@@ -313,19 +326,70 @@ interface RegExpOptions {
313
326
  */
314
327
  level?: 'error' | 'warn';
315
328
  }
316
- interface TailwindcssParserPerGlobOptions {
329
+ /**
330
+ * Interface for better-tailwindcss specific options.
331
+ */
332
+ interface TailwindCssOptions {
317
333
  /**
318
334
  * Provides a specific ESLint parser per glob pattern.
319
- * This is only needed if you want to lint tailwindcss without using Angular and TypeScript.
320
335
  */
321
336
  parsers?: Record<string, TSESLint.FlatConfig.Parser>;
337
+ /**
338
+ * Use all better-tailwindcss rules or only recommended ones.
339
+ *
340
+ * @default false
341
+ */
342
+ enableAllRules?: boolean;
343
+ /**
344
+ * The path to the entry file of the CSS-based tailwind config (eg: `src/global.css`). If not specified, the plugin will fall back to the default configuration.
345
+ * The tailwind config is used to determine the sorting order.
346
+ */
347
+ entryPoint?: string;
348
+ /**
349
+ * The path to the `tailwind.config.js` file. If not specified, the plugin will try to find it automatically or falls back to the default configuration.
350
+ * The tailwind config is used to determine the sorting order.
351
+ */
352
+ tailwindConfig?: string;
353
+ /**
354
+ * The name of the attribute that contains the tailwind classes.
355
+ *
356
+ * @default Name for `"class"` and strings Matcher for `"class", "className"`.
357
+ */
358
+ attributes?: Attributes;
359
+ /**
360
+ * List of function names which arguments should also get linted.
361
+ *
362
+ * @default Matchers for `"cc", "clb", "clsx", "cn", "cnb", "ctl", "cva", "cx", "dcnb", "objstr", "tv", "twJoin", "twMerge"`.
363
+ */
364
+ callees?: Callees;
365
+ /**
366
+ * List of variable names whose initializer should also get linted.
367
+ *
368
+ * @default strings Matcher for `"className", "classNames", "classes", "style", "styles"`.
369
+ */
370
+ variables?: Variables;
371
+ /**
372
+ * List of template literal tag names whose content should get linted.
373
+ * When using the `tags` option, it is recommended to use the strings Matcher for your tag names. This will ensure that nested expressions get linted correctly.
374
+ *
375
+ * @default None
376
+ */
377
+ tags?: Tags;
378
+ }
379
+ interface ProjectTypeOptions {
380
+ /**
381
+ * Type of the project. `lib` will enable more strict rules for libraries.
382
+ *
383
+ * @default 'app'
384
+ */
385
+ type?: 'app' | 'lib';
322
386
  }
323
387
  /**
324
388
  * Options for creating an ESLint configuration.
325
389
  *
326
390
  * @see createConfig function
327
391
  */
328
- interface CreateConfigOptions {
392
+ interface CreateConfigOptions extends ProjectTypeOptions {
329
393
  /**
330
394
  * Enable gitignore support.
331
395
  *
@@ -394,7 +458,7 @@ interface CreateConfigOptions {
394
458
  *
395
459
  * @default false
396
460
  */
397
- tailwindcss?: boolean | (FilesOptions & OverridesOptions) | (OverridesOptions & TailwindcssParserPerGlobOptions);
461
+ tailwindcss?: boolean | (FilesOptions & OverridesOptions & TailwindCssOptions);
398
462
  /**
399
463
  * Enable JSONC support.
400
464
  *
@@ -483,11 +547,10 @@ declare function imports(options?: StylisticOptions): ConfigArray;
483
547
  *
484
548
  * @param options - Configuration options for the JavaScript setup.
485
549
  * @param options.overrides - Additional rule overrides.
486
- * @param options.allowAngularDecorator - Allows specific Angular decorators to be used without new-cap errors.
487
550
  * @returns A configuration array for ESLint.
488
551
  * @example
489
552
  * ```typescript
490
- * const config = javascript({ allowAngularDecorator: true });
553
+ * const config = javascript();
491
554
  * ```
492
555
  */
493
556
  declare function javascript(options?: OverridesOptions): ConfigArray;
@@ -624,18 +687,19 @@ declare const STYLISTIC_CONFIG_DEFAULT: StylisticConfig;
624
687
  declare function stylistic(options?: StylisticOptions): Promise<ConfigArray>;
625
688
 
626
689
  /**
627
- * Generates an ESLint configuration array for Tailwind CSS.
690
+ * Generates an ESLint configuration array for Tailwind CSS using better-tailwindcss plugin.
628
691
  *
629
692
  * @param [options] - Optional overrides for the configuration.
630
693
  * @returns A promise that resolves to the ESLint configuration array.
631
694
  * @example
632
695
  * const config = await tailwindcss({
696
+ * enableAllRules: true,
633
697
  * overrides: {
634
- * 'tailwindcss/classnames-order': 'warn',
698
+ * 'better-tailwindcss/recommended': 'warn',
635
699
  * },
636
700
  * });
637
701
  */
638
- declare function tailwindcss(options?: (FilesOptions & OverridesOptions) | (OverridesOptions & TailwindcssParserPerGlobOptions)): Promise<ConfigArray>;
702
+ declare function tailwindcss(options?: (FilesOptions & OverridesOptions & TailwindCssOptions)): Promise<ConfigArray>;
639
703
 
640
704
  /**
641
705
  * Generates an ESLint configuration for TOML files.
@@ -658,7 +722,7 @@ declare function toml(options?: FilesOptions & OverridesOptions & StylisticOptio
658
722
  * @param options.overrides - Additional rule overrides.
659
723
  * @returns A ConfigArray containing the TypeScript ESLint configuration.
660
724
  */
661
- declare function typescript(options?: OverridesOptions & StylisticOptions & TypeScriptErasableSyntaxOnlyOptions & TypeScriptParserOptions): Promise<ConfigArray>;
725
+ declare function typescript(options?: OverridesOptions & ProjectTypeOptions & StylisticOptions & TypeScriptErasableSyntaxOnlyOptions & TypeScriptParserOptions): Promise<ConfigArray>;
662
726
 
663
727
  /**
664
728
  * Generates a configuration array for the Unicorn plugin with the specified options.
@@ -805,4 +869,4 @@ type ResolvedOptions<T> = T extends boolean ? never : NonNullable<T>;
805
869
  declare function resolveSubOptions<K extends keyof CreateConfigOptions>(options: CreateConfigOptions, key: K): ResolvedOptions<CreateConfigOptions[K]>;
806
870
 
807
871
  export { GLOB_HTML, GLOB_JS, GLOB_SRC, GLOB_TESTS, GLOB_TS, STYLISTIC_CONFIG_DEFAULT, angular, comments, defineConfig, ensurePackages, findNearestPackageJsonName, getTsConfigFileName, getWorkspaceRoot, ignores, imports, interopDefault, isPackageInScope, javascript, jsdoc, jsonc, markdown, ngrx, perfectionist, regexp, resolveSubOptions, sortPackageJson, sortTsConfig, stylistic, tailwindcss, toml, typescript, unicorn, vitest, yaml };
808
- export type { AngularOptions, Awaitable, CreateConfigOptions, FilesOptions, FormattersOptions, NgrxOperators, NgrxOptions, OverridesOptions, RegExpOptions, ResolvedOptions, StylisticConfig, StylisticOptions, TailwindcssParserPerGlobOptions, TestingOptions, TypeScriptErasableSyntaxOnlyOptions, TypeScriptParserOptions, UnicornOptions };
872
+ export type { AngularOptions, Awaitable, CreateConfigOptions, FilesOptions, FormattersOptions, NgrxOperators, NgrxOptions, OverridesOptions, ProjectTypeOptions, RegExpOptions, ResolvedOptions, StylisticConfig, StylisticOptions, TailwindCssOptions, TestingOptions, TypeScriptErasableSyntaxOnlyOptions, TypeScriptParserOptions, UnicornOptions };
package/dist/index.mjs CHANGED
@@ -139,15 +139,26 @@ async function findNearestPackageJsonName(directoryPath = resolve()) {
139
139
  }
140
140
  }
141
141
  function resolveSubOptions(options, key) {
142
- if (typeof options[key] === "boolean") {
143
- return {};
142
+ const option = options[key];
143
+ if (typeof option === "boolean") {
144
+ throw new TypeError(`Option ${String(key)} should not be boolean.`);
144
145
  }
145
- return options[key] ?? {};
146
+ return option ?? {};
146
147
  }
147
148
 
148
149
  async function angular(options = {}) {
149
150
  const angularEslint = await interopDefault(import('angular-eslint'));
150
- const { enableAccessibilityRules = true, tsOverrides = {}, htmlOverrides = {}, prefix = "app", ignoreClassNamePatternForInjectableProvidedIn: ignoreClassNamePattern, componentStylesMode = "string", preferOnPushOnly = true } = options;
151
+ const {
152
+ enableAccessibilityRules = true,
153
+ tsOverrides = {},
154
+ htmlOverrides = {},
155
+ prefix = "app",
156
+ ignoreClassNamePatternForInjectableProvidedIn: ignoreClassNamePattern,
157
+ componentStylesMode = "string",
158
+ preferOnPushOnly = true,
159
+ banExperimentalApi = true,
160
+ banDeveloperPreviewApi = true
161
+ } = options;
151
162
  return tseslint.config(
152
163
  {
153
164
  name: "fabdeh/angular/rules",
@@ -208,7 +219,9 @@ async function angular(options = {}) {
208
219
  "@angular-eslint/no-async-lifecycle-method": "error",
209
220
  "@angular-eslint/no-attribute-decorator": "error",
210
221
  "@angular-eslint/no-conflicting-lifecycle": "error",
222
+ ...banDeveloperPreviewApi ? { "@angular-eslint/no-developer-preview": "error" } : {},
211
223
  "@angular-eslint/no-duplicates-in-metadata-arrays": "error",
224
+ ...banExperimentalApi ? { "@angular-eslint/no-experimental": "error" } : {},
212
225
  "@angular-eslint/no-forward-ref": "error",
213
226
  "@angular-eslint/no-lifecycle-call": "error",
214
227
  "@angular-eslint/no-pipe-impure": "error",
@@ -404,7 +417,27 @@ function javascript(options = {}) {
404
417
  "no-octal-escape": "error",
405
418
  "no-plusplus": ["error", { allowForLoopAfterthoughts: true }],
406
419
  "no-proto": "error",
407
- "no-restricted-syntax": ["error", "TSEnumDeclaration[const=true]", "TSExportAssignment", "ForInStatement"],
420
+ /*
421
+ 'no-restricted-syntax': [
422
+ 'error',
423
+ {
424
+ selector: 'TSEnumDeclaration',
425
+ message: '',
426
+ },
427
+ {
428
+ selector: 'TSExportAssignment',
429
+ message: '',
430
+ },
431
+ {
432
+ selector: 'ForInStatement',
433
+ message: '',
434
+ },
435
+ {
436
+ selector: ':matches(PropertyDefinition, MethodDefinition)[accessibility="private"]',
437
+ message: 'Use `#private` members instead.',
438
+ },
439
+ ],
440
+ */
408
441
  "no-self-compare": "error",
409
442
  "no-sequences": "error",
410
443
  "no-template-curly-in-string": "error",
@@ -1231,42 +1264,43 @@ async function stylistic(options = {}) {
1231
1264
  });
1232
1265
  }
1233
1266
 
1234
- function isTailwindcssParserPerGlobOptions(options) {
1235
- return "parsers" in options && options.parsers !== void 0;
1236
- }
1237
1267
  async function tailwindcss(options = {}) {
1238
- await ensurePackages(["eslint-plugin-tailwindcss"]);
1239
- const tailwindcssPlugin = await interopDefault(import('eslint-plugin-tailwindcss'));
1268
+ await ensurePackages(["eslint-plugin-better-tailwindcss"]);
1269
+ const betterTailwindcssPlugin = await interopDefault(import('eslint-plugin-better-tailwindcss'));
1270
+ const { files: filesGlob, overrides, enableAllRules, parsers, ...settings } = options;
1240
1271
  let files;
1241
1272
  let parserConfigs;
1242
- const { overrides = {} } = options;
1243
- if (isTailwindcssParserPerGlobOptions(options)) {
1244
- const parsers = options.parsers ?? {};
1273
+ if (parsers) {
1245
1274
  files = { files: [...new Set(Object.keys(parsers))] };
1246
1275
  parserConfigs = Object.entries(parsers).map(([glob, parser], index) => ({
1247
1276
  name: `fabdeh/tailwindcss/parser-${index + 1}`,
1248
- file: [glob],
1277
+ files: [glob],
1249
1278
  languageOptions: {
1250
1279
  parser
1251
1280
  }
1252
1281
  }));
1253
1282
  } else {
1254
- files = { files: options.files ?? [GLOB_SRC, GLOB_HTML] };
1283
+ files = { files: filesGlob ?? [GLOB_SRC, GLOB_HTML] };
1255
1284
  parserConfigs = [];
1256
1285
  }
1257
1286
  return tseslint.config(
1258
1287
  ...parserConfigs,
1259
1288
  {
1260
- name: "fabdeh/tailwindcss/rules",
1261
- plugins: { tailwindcss: tailwindcssPlugin },
1289
+ name: "@fabdeh/tailwindcss/rules",
1262
1290
  ...files,
1291
+ plugins: {
1292
+ "better-tailwindcss": betterTailwindcssPlugin
1293
+ },
1294
+ settings: {
1295
+ "better-tailwindcss": settings
1296
+ },
1263
1297
  rules: {
1264
- "tailwindcss/classnames-order": "error",
1265
- "tailwindcss/enforces-negative-arbitrary-values": "error",
1266
- "tailwindcss/enforces-shorthand": "error",
1267
- "tailwindcss/no-contradicting-classname": "error",
1268
- "tailwindcss/no-unnecessary-arbitrary-value": "error",
1269
- ...overrides
1298
+ ...betterTailwindcssPlugin.configs.recommended.rules,
1299
+ ...enableAllRules ? {
1300
+ "better-tailwindcss/enforce-consistent-variable-syntax": "warn",
1301
+ "better-tailwindcss/no-conflicting-classes": "error",
1302
+ "better-tailwindcss/no-restricted-classes": "error"
1303
+ } : {}
1270
1304
  }
1271
1305
  }
1272
1306
  );
@@ -1347,7 +1381,7 @@ const memberOrdering = {
1347
1381
  };
1348
1382
 
1349
1383
  async function typescript(options = {}) {
1350
- const { stylistic = true, parserOptions = {}, overrides = {}, enableErasableSyntaxOnly = false } = options;
1384
+ const { stylistic = true, parserOptions = {}, overrides = {}, enableErasableSyntaxOnly = false, type = "app" } = options;
1351
1385
  let erasableSyntaxOnlyPlugin;
1352
1386
  let erasableSyntaxOnlyRules;
1353
1387
  if (enableErasableSyntaxOnly) {
@@ -1403,17 +1437,15 @@ async function typescript(options = {}) {
1403
1437
  prefer: "type-imports"
1404
1438
  }],
1405
1439
  "@typescript-eslint/dot-notation": "error",
1406
- "@typescript-eslint/explicit-module-boundary-types": "error",
1407
- "@typescript-eslint/explicit-function-return-type": [
1408
- "error",
1409
- {
1410
- allowExpressions: true,
1411
- allowTypedFunctionExpressions: true,
1412
- allowHigherOrderFunctions: true,
1413
- allowDirectConstAssertionInArrowFunctions: true,
1414
- allowConciseArrowFunctionExpressionsStartingWithVoid: true
1415
- }
1416
- ],
1440
+ ...type === "lib" ? {
1441
+ "@typescript-eslint/explicit-function-return-type": [
1442
+ "error",
1443
+ {
1444
+ allowExpressions: true,
1445
+ allowIIFEs: true
1446
+ }
1447
+ ]
1448
+ } : { "@typescript-eslint/explicit-module-boundary-types": "error" },
1417
1449
  "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }],
1418
1450
  "@typescript-eslint/member-ordering": ["error", memberOrdering],
1419
1451
  "@typescript-eslint/method-signature-style": "error",
@@ -1959,7 +1991,8 @@ async function defineConfig(options = {}, ...userConfigs) {
1959
1991
  const typescriptOptions = resolveSubOptions(options, "typescript");
1960
1992
  configs.push(typescript({
1961
1993
  ...typescriptOptions,
1962
- stylistic: stylisticOptions
1994
+ stylistic: stylisticOptions,
1995
+ type: options.type
1963
1996
  }));
1964
1997
  }
1965
1998
  if (stylisticOptions) {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@fabdeh/eslint-config",
3
3
  "type": "module",
4
- "version": "0.5.0",
5
- "packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39",
4
+ "version": "0.6.1",
5
+ "packageManager": "pnpm@10.12.4+sha512.5ea8b0deed94ed68691c9bad4c955492705c5eeb8a87ef86bc62c74a26b037b08ff9570f108b2e4dbd1dd1a9186fea925e527f141c648e85af45631074680184",
6
6
  "description": "My personal eslint config preset",
7
7
  "author": {
8
8
  "name": "Fabien Dehopré",
@@ -55,22 +55,22 @@
55
55
  "peerDependencies": {
56
56
  "@prettier/plugin-xml": "^3.4.1",
57
57
  "eslint": "^9.21.0",
58
+ "eslint-plugin-better-tailwindcss": "^3.4.1",
58
59
  "eslint-plugin-erasable-syntax-only": "^0.3.0",
59
60
  "eslint-plugin-format": "^1.0.1",
60
- "eslint-plugin-tailwindcss": "^3.18.0",
61
61
  "prettier-plugin-slidev": "^1.0.5"
62
62
  },
63
63
  "peerDependenciesMeta": {
64
64
  "@prettier/plugin-xml": {
65
65
  "optional": true
66
66
  },
67
- "eslint-plugin-erasable-syntax-only": {
67
+ "eslint-plugin-better-tailwindcss": {
68
68
  "optional": true
69
69
  },
70
- "eslint-plugin-format": {
70
+ "eslint-plugin-erasable-syntax-only": {
71
71
  "optional": true
72
72
  },
73
- "eslint-plugin-tailwindcss": {
73
+ "eslint-plugin-format": {
74
74
  "optional": true
75
75
  },
76
76
  "prettier-plugin-slidev": {
@@ -81,39 +81,39 @@
81
81
  "@antfu/install-pkg": "^1.1.0",
82
82
  "@clack/prompts": "^0.10.1",
83
83
  "@eslint-community/eslint-plugin-eslint-comments": "^4.5.0",
84
- "@eslint/js": "^9.28.0",
85
- "@eslint/markdown": "^6.5.0",
84
+ "@eslint/js": "^9.30.1",
85
+ "@eslint/markdown": "^6.6.0",
86
86
  "@ngrx/eslint-plugin": "^19.2.1",
87
87
  "@stylistic/eslint-plugin": "^4.4.1",
88
- "@typescript-eslint/eslint-plugin": "^8.33.1",
89
- "@typescript-eslint/parser": "^8.33.1",
90
- "@typescript-eslint/utils": "^8.33.1",
91
- "@vitest/eslint-plugin": "^1.2.1",
92
- "angular-eslint": "^20.0.0",
88
+ "@typescript-eslint/eslint-plugin": "^8.35.1",
89
+ "@typescript-eslint/parser": "^8.35.1",
90
+ "@typescript-eslint/utils": "^8.35.1",
91
+ "@vitest/eslint-plugin": "^1.3.4",
92
+ "angular-eslint": "^20.1.1",
93
93
  "eslint-config-flat-gitignore": "^2.1.0",
94
94
  "eslint-flat-config-utils": "^2.1.0",
95
95
  "eslint-merge-processors": "^2.0.0",
96
- "eslint-plugin-import-x": "^4.15.1",
96
+ "eslint-plugin-import-x": "^4.16.1",
97
97
  "eslint-plugin-jest-dom": "^5.5.0",
98
- "eslint-plugin-jsdoc": "^50.7.1",
98
+ "eslint-plugin-jsdoc": "^50.8.0",
99
99
  "eslint-plugin-jsonc": "^2.20.1",
100
- "eslint-plugin-perfectionist": "^4.14.0",
100
+ "eslint-plugin-perfectionist": "^4.15.0",
101
101
  "eslint-plugin-prefer-arrow-functions": "^3.6.2",
102
- "eslint-plugin-regexp": "^2.8.0",
103
- "eslint-plugin-testing-library": "^7.4.0",
102
+ "eslint-plugin-regexp": "^2.9.0",
103
+ "eslint-plugin-testing-library": "^7.5.3",
104
104
  "eslint-plugin-toml": "^0.12.0",
105
105
  "eslint-plugin-unicorn": "^59.0.1",
106
106
  "eslint-plugin-unused-imports": "^4.1.4",
107
107
  "eslint-plugin-yml": "^1.18.0",
108
- "globals": "^16.2.0",
108
+ "globals": "^16.3.0",
109
109
  "jsonc-eslint-parser": "^2.4.0",
110
110
  "local-pkg": "^1.1.1",
111
111
  "toml-eslint-parser": "^0.10.0",
112
- "typescript-eslint": "^8.33.1",
112
+ "typescript-eslint": "^8.35.1",
113
113
  "yaml-eslint-parser": "^1.3.0"
114
114
  },
115
115
  "devDependencies": {
116
- "@angular/core": "^20.0.2",
116
+ "@angular/core": "^20.0.6",
117
117
  "@commitlint/cli": "^19.8.1",
118
118
  "@commitlint/config-conventional": "^19.8.1",
119
119
  "@commitlint/cz-commitlint": "^19.8.1",
@@ -126,14 +126,14 @@
126
126
  "@testing-library/angular": "^17.4.0",
127
127
  "@testing-library/jest-dom": "^6.6.3",
128
128
  "@types/fs-extra": "^11.0.4",
129
- "@types/node": "^22.15.30",
130
- "bumpp": "^10.1.1",
131
- "changelogithub": "^13.15.0",
129
+ "@types/node": "^22.16.0",
130
+ "bumpp": "^10.2.0",
131
+ "changelogithub": "^13.16.0",
132
132
  "commitizen": "^4.3.1",
133
- "eslint": "^9.28.0",
133
+ "eslint": "^9.30.1",
134
+ "eslint-plugin-better-tailwindcss": "^3.4.3",
134
135
  "eslint-plugin-erasable-syntax-only": "^0.3.1",
135
136
  "eslint-plugin-format": "^1.0.1",
136
- "eslint-plugin-tailwindcss": "^3.18.0",
137
137
  "execa": "^9.6.0",
138
138
  "fast-glob": "^3.3.3",
139
139
  "fs-extra": "^11.3.0",
@@ -143,10 +143,10 @@
143
143
  "nano-staged": "^0.8.0",
144
144
  "prettier-plugin-slidev": "^1.0.5",
145
145
  "simple-git-hooks": "^2.13.0",
146
- "tailwindcss": "^3.4.17",
146
+ "tailwindcss": "^4.1.11",
147
147
  "typescript": "^5.8.3",
148
148
  "unbuild": "^3.5.0",
149
- "vitest": "^3.2.2"
149
+ "vitest": "^3.2.4"
150
150
  },
151
151
  "pnpm": {
152
152
  "overrides": {