eslint-config-axkit 1.5.0 → 1.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/README.md +8 -3
- package/dist/base-config.d.ts +2 -1
- package/dist/base-config.d.ts.map +1 -0
- package/dist/base-config.js +82 -74
- package/dist/base-config.js.map +1 -0
- package/dist/create-vitest-config.d.ts +16 -0
- package/dist/create-vitest-config.d.ts.map +1 -0
- package/dist/create-vitest-config.js +64 -0
- package/dist/create-vitest-config.js.map +1 -0
- package/dist/import-optional.d.ts +1 -0
- package/dist/import-optional.d.ts.map +1 -0
- package/dist/import-optional.js +1 -0
- package/dist/import-optional.js.map +1 -0
- package/dist/index.d.ts +12 -4
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -8
- package/dist/index.js.map +1 -0
- package/dist/node-test-config.d.ts +9 -0
- package/dist/node-test-config.d.ts.map +1 -0
- package/dist/node-test-config.js +28 -0
- package/dist/node-test-config.js.map +1 -0
- package/package.json +33 -31
- package/dist/vitest-config.d.ts +0 -2
- package/dist/vitest-config.js +0 -62
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# eslint-config-axkit
|
|
2
2
|
|
|
3
|
-
Reusable ESLint flat config for TypeScript + Node.js projects with strict type checking, Prettier,
|
|
3
|
+
Reusable ESLint flat config for TypeScript + Node.js projects with strict type checking, Prettier, and Unicorn.
|
|
4
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
@@ -60,6 +60,8 @@ export default axkit();
|
|
|
60
60
|
|
|
61
61
|
For the current rule set and presets, see the source code in `src/`.
|
|
62
62
|
|
|
63
|
+
By default, axkit ignores files under `.agents/` and `.claude/`.
|
|
64
|
+
|
|
63
65
|
## Extending the Config
|
|
64
66
|
|
|
65
67
|
Add additional rules or override existing ones by spreading additional config objects:
|
|
@@ -86,14 +88,17 @@ export default [
|
|
|
86
88
|
| Option | Type | Description |
|
|
87
89
|
| --------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
88
90
|
| `gitignorePath` | `string` | Path to `.gitignore` file. Patterns will be added to ESLint's ignore list. |
|
|
91
|
+
| `vitest` | `boolean` | Enable Vitest ESLint rules for test files. Requires `@vitest/eslint-plugin` to be installed. |
|
|
89
92
|
| `fastify` | `boolean` | Relax rules that conflict with idiomatic Fastify patterns. Configures `unicorn/prevent-abbreviations` with an allowList for common terms (`app`, `db`, `req`, etc.) and disables `@typescript-eslint/require-await` and `@typescript-eslint/strict-void-return`. |
|
|
90
|
-
| `nextjs` | `boolean` | Enable Next.js rules (`eslint-config-next` core-web-vitals + typescript). Requires `eslint-config-next` to be installed.
|
|
93
|
+
| `nextjs` | `boolean` | Enable Next.js rules (`eslint-config-next` core-web-vitals + typescript) and React Fast Refresh (`only-export-components`) for `.tsx`/`.jsx` files. Requires `eslint-config-next` and `eslint-plugin-react-refresh` to be installed. |
|
|
91
94
|
| `storybook` | `boolean` | Enable Storybook rules (`eslint-plugin-storybook` flat/recommended). Requires `eslint-plugin-storybook` to be installed. |
|
|
92
95
|
| `tailwindcss` | `string` | Path to the Tailwind CSS entry point (e.g. `"src/app/globals.css"`). Enables `eslint-plugin-better-tailwindcss` recommended rules enforcing stylistic and correctness rules. Requires `eslint-plugin-better-tailwindcss` to be installed. |
|
|
93
96
|
|
|
97
|
+
Axkit includes a built-in narrow allowlist entry for `scripts/export-release-version-plugin.mjs`, which is used by repositories managed with `verify-repository`.
|
|
98
|
+
|
|
94
99
|
## Requirements
|
|
95
100
|
|
|
96
|
-
- Node.js >= 22.
|
|
101
|
+
- Node.js >= 22.19.0
|
|
97
102
|
- ESLint >= 10
|
|
98
103
|
|
|
99
104
|
## License
|
package/dist/base-config.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-config.d.ts","sourceRoot":"","sources":["../src/base-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAMrC,wBAAgB,gBAAgB,IAAI,MAAM,CAAC,MAAM,CAsGhD"}
|
package/dist/base-config.js
CHANGED
|
@@ -1,76 +1,84 @@
|
|
|
1
1
|
import globals from "globals";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
const DEFAULT_PROJECT_SERVICE_ALLOW_DEFAULT_PROJECT = [
|
|
3
|
+
"scripts/export-release-version-plugin.mjs",
|
|
4
|
+
];
|
|
5
|
+
export function createBaseConfig() {
|
|
6
|
+
return {
|
|
7
|
+
name: "axkit/base",
|
|
8
|
+
files: ["**/*.{js,mjs,cjs,ts,tsx,mts,cts}"],
|
|
9
|
+
languageOptions: {
|
|
10
|
+
globals: globals.node,
|
|
11
|
+
parserOptions: {
|
|
12
|
+
projectService: {
|
|
13
|
+
allowDefaultProject: DEFAULT_PROJECT_SERVICE_ALLOW_DEFAULT_PROJECT,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
9
16
|
},
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
}
|
|
17
|
+
rules: {
|
|
18
|
+
// Security rules
|
|
19
|
+
"no-eval": "error",
|
|
20
|
+
"no-new-func": "error",
|
|
21
|
+
"no-script-url": "error",
|
|
22
|
+
// Correctness rules
|
|
23
|
+
"no-return-assign": ["error", "always"],
|
|
24
|
+
radix: ["error", "as-needed"],
|
|
25
|
+
"guard-for-in": "error",
|
|
26
|
+
"prefer-object-has-own": "error",
|
|
27
|
+
// Clarity rules
|
|
28
|
+
"prefer-regex-literals": ["error", { disallowRedundantWrapping: true }],
|
|
29
|
+
"require-unicode-regexp": "error",
|
|
30
|
+
"no-extend-native": "error",
|
|
31
|
+
"no-new-wrappers": "error",
|
|
32
|
+
"no-implicit-coercion": ["error", { allow: ["!!"] }],
|
|
33
|
+
// Allow numbers in template literals (safe and common)
|
|
34
|
+
"@typescript-eslint/restrict-template-expressions": [
|
|
35
|
+
"error",
|
|
36
|
+
{ allowNumber: true },
|
|
37
|
+
],
|
|
38
|
+
// Disallow value-returning functions where void-returning expected
|
|
39
|
+
"@typescript-eslint/strict-void-return": "error",
|
|
40
|
+
// Disallow unused private class members (extends ESLint rule for TS private keyword)
|
|
41
|
+
"@typescript-eslint/no-unused-private-class-members": "error",
|
|
42
|
+
// ===== ESLint Core Bug Prevention =====
|
|
43
|
+
// Catch missing returns in array methods (.map, .filter, etc.)
|
|
44
|
+
"array-callback-return": ["error", { allowImplicit: false }],
|
|
45
|
+
// Constructors shouldn't return values
|
|
46
|
+
"no-constructor-return": "error",
|
|
47
|
+
// Returns in Promise executors are meaningless
|
|
48
|
+
"no-promise-executor-return": "error",
|
|
49
|
+
// Comparing variable to itself is always a bug
|
|
50
|
+
"no-self-compare": "error",
|
|
51
|
+
// Catch template literal syntax in regular strings
|
|
52
|
+
"no-template-curly-in-string": "error",
|
|
53
|
+
// Loops that only run once are bugs
|
|
54
|
+
"no-unreachable-loop": "error",
|
|
55
|
+
// Infinite loop detection (loop condition never changes)
|
|
56
|
+
"no-unmodified-loop-condition": "error",
|
|
57
|
+
// Dead code - assignments never read
|
|
58
|
+
"no-useless-assignment": "error",
|
|
59
|
+
// Race condition detection in async code
|
|
60
|
+
"require-atomic-updates": "error",
|
|
61
|
+
// Require === and !== (allow == null for null/undefined check)
|
|
62
|
+
eqeqeq: ["error", "always", { null: "ignore" }],
|
|
63
|
+
// Comma operator is confusing
|
|
64
|
+
"no-sequences": "error",
|
|
65
|
+
// ===== TypeScript-ESLint Enhancements =====
|
|
66
|
+
// Ensure switch statements handle all enum/union cases
|
|
67
|
+
"@typescript-eslint/switch-exhaustiveness-check": "error",
|
|
68
|
+
// Use ?. instead of && chains (safer and cleaner)
|
|
69
|
+
"@typescript-eslint/prefer-optional-chain": "error",
|
|
70
|
+
// Require compare function for sort() to prevent string sorting bugs
|
|
71
|
+
"@typescript-eslint/require-array-sort-compare": "error",
|
|
72
|
+
// Prevent confusing ! placement next to == or !=
|
|
73
|
+
"@typescript-eslint/no-confusing-non-null-assertion": "error",
|
|
74
|
+
// Enforce import type for type-only imports
|
|
75
|
+
"@typescript-eslint/consistent-type-imports": [
|
|
76
|
+
"error",
|
|
77
|
+
{ prefer: "type-imports" },
|
|
78
|
+
],
|
|
79
|
+
// Enforce export type for type-only exports
|
|
80
|
+
"@typescript-eslint/consistent-type-exports": "error",
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=base-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-config.js","sourceRoot":"","sources":["../src/base-config.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAG9B,MAAM,6CAA6C,GAAG;IACpD,2CAA2C;CAC5C,CAAC;AAEF,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,CAAC,kCAAkC,CAAC;QAC3C,eAAe,EAAE;YACf,OAAO,EAAE,OAAO,CAAC,IAAI;YACrB,aAAa,EAAE;gBACb,cAAc,EAAE;oBACd,mBAAmB,EAAE,6CAA6C;iBACnE;aACF;SACF;QACD,KAAK,EAAE;YACL,iBAAiB;YACjB,SAAS,EAAE,OAAO;YAClB,aAAa,EAAE,OAAO;YACtB,eAAe,EAAE,OAAO;YAExB,oBAAoB;YACpB,kBAAkB,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;YACvC,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC;YAC7B,cAAc,EAAE,OAAO;YACvB,uBAAuB,EAAE,OAAO;YAEhC,gBAAgB;YAChB,uBAAuB,EAAE,CAAC,OAAO,EAAE,EAAE,yBAAyB,EAAE,IAAI,EAAE,CAAC;YACvE,wBAAwB,EAAE,OAAO;YACjC,kBAAkB,EAAE,OAAO;YAC3B,iBAAiB,EAAE,OAAO;YAC1B,sBAAsB,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAEpD,uDAAuD;YACvD,kDAAkD,EAAE;gBAClD,OAAO;gBACP,EAAE,WAAW,EAAE,IAAI,EAAE;aACtB;YAED,mEAAmE;YACnE,uCAAuC,EAAE,OAAO;YAEhD,qFAAqF;YACrF,oDAAoD,EAAE,OAAO;YAE7D,yCAAyC;YAEzC,+DAA+D;YAC/D,uBAAuB,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;YAE5D,uCAAuC;YACvC,uBAAuB,EAAE,OAAO;YAEhC,+CAA+C;YAC/C,4BAA4B,EAAE,OAAO;YAErC,+CAA+C;YAC/C,iBAAiB,EAAE,OAAO;YAE1B,mDAAmD;YACnD,6BAA6B,EAAE,OAAO;YAEtC,oCAAoC;YACpC,qBAAqB,EAAE,OAAO;YAE9B,yDAAyD;YACzD,8BAA8B,EAAE,OAAO;YAEvC,qCAAqC;YACrC,uBAAuB,EAAE,OAAO;YAEhC,yCAAyC;YACzC,wBAAwB,EAAE,OAAO;YAEjC,+DAA+D;YAC/D,MAAM,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;YAE/C,8BAA8B;YAC9B,cAAc,EAAE,OAAO;YAEvB,6CAA6C;YAE7C,uDAAuD;YACvD,gDAAgD,EAAE,OAAO;YAEzD,kDAAkD;YAClD,0CAA0C,EAAE,OAAO;YAEnD,qEAAqE;YACrE,+CAA+C,EAAE,OAAO;YAExD,iDAAiD;YACjD,oDAAoD,EAAE,OAAO;YAE7D,4CAA4C;YAC5C,4CAA4C,EAAE;gBAC5C,OAAO;gBACP,EAAE,MAAM,EAAE,cAAc,EAAE;aAC3B;YAED,4CAA4C;YAC5C,4CAA4C,EAAE,OAAO;SACtD;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Linter } from "eslint";
|
|
2
|
+
type VitestPlugin = {
|
|
3
|
+
configs: {
|
|
4
|
+
recommended: {
|
|
5
|
+
rules: Linter.RulesRecord;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
environments: {
|
|
9
|
+
env: {
|
|
10
|
+
globals: Record<string, boolean>;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export declare function createVitestConfig(vitest: VitestPlugin): Linter.Config;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=create-vitest-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-vitest-config.d.ts","sourceRoot":"","sources":["../src/create-vitest-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,KAAK,YAAY,GAAG;IAClB,OAAO,EAAE;QAAE,WAAW,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC,WAAW,CAAA;SAAE,CAAA;KAAE,CAAC;IACxD,YAAY,EAAE;QAAE,GAAG,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAAE,CAAA;KAAE,CAAC;CAC7D,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,CAuFtE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export function createVitestConfig(vitest) {
|
|
2
|
+
return {
|
|
3
|
+
name: "axkit/vitest",
|
|
4
|
+
files: [
|
|
5
|
+
"**/*.{test,spec}.{ts,tsx,js,mjs,cjs,mts,cts}",
|
|
6
|
+
"tests/**/*.{ts,tsx,js,mjs,cjs,mts,cts}",
|
|
7
|
+
],
|
|
8
|
+
plugins: { vitest },
|
|
9
|
+
rules: {
|
|
10
|
+
...vitest.configs.recommended.rules,
|
|
11
|
+
// Ensure expect.poll() and expect.element() are awaited
|
|
12
|
+
"vitest/require-awaited-expect-poll": "error",
|
|
13
|
+
// Keep vi.mock() and other hoisted APIs at the top of files
|
|
14
|
+
"vitest/hoisted-apis-on-top": "warn",
|
|
15
|
+
// Prefer toHaveBeenCalledTimes() matcher
|
|
16
|
+
"vitest/prefer-to-have-been-called-times": "warn",
|
|
17
|
+
// Prefer mockResolvedValue() over mockImplementation(() => Promise.resolve())
|
|
18
|
+
"vitest/prefer-mock-promise-shorthand": "warn",
|
|
19
|
+
// Prefer expectTypeOf() for type testing
|
|
20
|
+
"vitest/prefer-expect-type-of": "warn",
|
|
21
|
+
// Enforce consistent use of .each vs .for for parameterized tests
|
|
22
|
+
"vitest/consistent-each-for": "warn",
|
|
23
|
+
// Keep hooks (beforeEach, afterEach, etc.) at the top of describe blocks
|
|
24
|
+
"vitest/prefer-hooks-on-top": "warn",
|
|
25
|
+
// ===== Test Logic Errors =====
|
|
26
|
+
// No conditionals (if/else) inside test bodies - tests should be deterministic
|
|
27
|
+
"vitest/no-conditional-in-test": "error",
|
|
28
|
+
// No conditionally defined tests - tests should always run
|
|
29
|
+
"vitest/no-conditional-tests": "error",
|
|
30
|
+
// No return statements in tests - just execute assertions
|
|
31
|
+
"vitest/no-test-return-statement": "warn",
|
|
32
|
+
// No duplicate lifecycle hooks
|
|
33
|
+
"vitest/no-duplicate-hooks": "warn",
|
|
34
|
+
// ===== Better Matchers (auto-fixable) =====
|
|
35
|
+
// Use toBe() for primitives (strict equality)
|
|
36
|
+
"vitest/prefer-to-be": "warn",
|
|
37
|
+
// Use toHaveLength() instead of expect(arr.length).toBe()
|
|
38
|
+
"vitest/prefer-to-have-length": "warn",
|
|
39
|
+
// Use toContain() instead of expect(arr.includes()).toBe(true)
|
|
40
|
+
"vitest/prefer-to-contain": "warn",
|
|
41
|
+
// Use toBeGreaterThan(), toBeLessThan(), etc.
|
|
42
|
+
"vitest/prefer-comparison-matcher": "warn",
|
|
43
|
+
// Use dedicated equality matchers
|
|
44
|
+
"vitest/prefer-equality-matcher": "warn",
|
|
45
|
+
// ===== Best Practices =====
|
|
46
|
+
// Use vi.spyOn() instead of direct property assignment
|
|
47
|
+
"vitest/prefer-spy-on": "warn",
|
|
48
|
+
// Use test.todo() for empty/placeholder tests
|
|
49
|
+
"vitest/prefer-todo": "warn",
|
|
50
|
+
// Use expect().resolves instead of expect(await promise)
|
|
51
|
+
"vitest/prefer-expect-resolves": "warn",
|
|
52
|
+
// No deprecated alias methods (toBeCalled → toHaveBeenCalled)
|
|
53
|
+
"vitest/no-alias-methods": "warn",
|
|
54
|
+
// Use vi.mocked() instead of type casting
|
|
55
|
+
"vitest/prefer-vi-mocked": "warn",
|
|
56
|
+
// Use .only/.skip instead of f/x prefixes
|
|
57
|
+
"vitest/no-test-prefixes": "warn",
|
|
58
|
+
},
|
|
59
|
+
languageOptions: {
|
|
60
|
+
globals: { ...vitest.environments.env.globals },
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=create-vitest-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-vitest-config.js","sourceRoot":"","sources":["../src/create-vitest-config.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,kBAAkB,CAAC,MAAoB;IACrD,OAAO;QACL,IAAI,EAAE,cAAc;QACpB,KAAK,EAAE;YACL,8CAA8C;YAC9C,wCAAwC;SACzC;QACD,OAAO,EAAE,EAAE,MAAM,EAAE;QACnB,KAAK,EAAE;YACL,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK;YAEnC,wDAAwD;YACxD,oCAAoC,EAAE,OAAO;YAE7C,4DAA4D;YAC5D,4BAA4B,EAAE,MAAM;YAEpC,yCAAyC;YACzC,yCAAyC,EAAE,MAAM;YAEjD,8EAA8E;YAC9E,sCAAsC,EAAE,MAAM;YAE9C,yCAAyC;YACzC,8BAA8B,EAAE,MAAM;YAEtC,kEAAkE;YAClE,4BAA4B,EAAE,MAAM;YAEpC,yEAAyE;YACzE,4BAA4B,EAAE,MAAM;YAEpC,gCAAgC;YAEhC,+EAA+E;YAC/E,+BAA+B,EAAE,OAAO;YAExC,2DAA2D;YAC3D,6BAA6B,EAAE,OAAO;YAEtC,0DAA0D;YAC1D,iCAAiC,EAAE,MAAM;YAEzC,+BAA+B;YAC/B,2BAA2B,EAAE,MAAM;YAEnC,6CAA6C;YAE7C,8CAA8C;YAC9C,qBAAqB,EAAE,MAAM;YAE7B,0DAA0D;YAC1D,8BAA8B,EAAE,MAAM;YAEtC,+DAA+D;YAC/D,0BAA0B,EAAE,MAAM;YAElC,8CAA8C;YAC9C,kCAAkC,EAAE,MAAM;YAE1C,kCAAkC;YAClC,gCAAgC,EAAE,MAAM;YAExC,6BAA6B;YAE7B,uDAAuD;YACvD,sBAAsB,EAAE,MAAM;YAE9B,8CAA8C;YAC9C,oBAAoB,EAAE,MAAM;YAE5B,yDAAyD;YACzD,+BAA+B,EAAE,MAAM;YAEvC,8DAA8D;YAC9D,yBAAyB,EAAE,MAAM;YAEjC,0CAA0C;YAC1C,yBAAyB,EAAE,MAAM;YAEjC,0CAA0C;YAC1C,yBAAyB,EAAE,MAAM;SAClC;QACD,eAAe,EAAE;YACf,OAAO,EAAE,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE;SAChD;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-optional.d.ts","sourceRoot":"","sources":["../src/import-optional.ts"],"names":[],"mappings":"AAaA;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUnE"}
|
package/dist/import-optional.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-optional.js","sourceRoot":"","sources":["../src/import-optional.ts"],"names":[],"mappings":";;;;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,eAAe,GAAG,aAAa,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAE3D,KAAK,UAAU,aAAa,CAAC,YAAoB;IAC/C,MAAM,QAAQ,GAAG,CAAC,MAAM,MAAM,kCAAC,aAAa,CAAC,YAAY,CAAC,CAAC,IAAI,EAAC,CAG/D,CAAC;IACF,OAAO,QAAQ,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,IAAI,YAAoB,CAAC;IACzB,IAAI,CAAC;QACH,YAAY,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,yBAAyB,IAAI,4DAA4D,IAAI,EAAE,CAChG,CAAC;IACJ,CAAC;IACD,OAAO,aAAa,CAAC,YAAY,CAAC,CAAC;AACrC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,11 +6,16 @@ export type Options = {
|
|
|
6
6
|
*/
|
|
7
7
|
gitignorePath?: string;
|
|
8
8
|
/**
|
|
9
|
-
* Enable Next.js rules (eslint-config-next core-web-vitals + typescript)
|
|
10
|
-
*
|
|
11
|
-
* Requires `eslint-config-next` to be installed.
|
|
9
|
+
* Enable Next.js rules (eslint-config-next core-web-vitals + typescript)
|
|
10
|
+
* and React Fast Refresh (`only-export-components`) for `.tsx`/`.jsx` files.
|
|
11
|
+
* Requires `eslint-config-next` and `eslint-plugin-react-refresh` to be installed.
|
|
12
12
|
*/
|
|
13
13
|
nextjs?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Enable Vitest ESLint rules for test files.
|
|
16
|
+
* Requires `@vitest/eslint-plugin` to be installed.
|
|
17
|
+
*/
|
|
18
|
+
vitest?: boolean;
|
|
14
19
|
/**
|
|
15
20
|
* Relax rules that conflict with idiomatic Fastify patterns:
|
|
16
21
|
* - `unicorn/prevent-abbreviations` — configured with allowList for common Fastify terms (`app`, `db`, `req`, `res`, `opts`, `params`, etc.)
|
|
@@ -38,12 +43,15 @@ export type Options = {
|
|
|
38
43
|
* - ESLint recommended rules
|
|
39
44
|
* - TypeScript strict type checking
|
|
40
45
|
* - Unicorn plugin (recommended)
|
|
41
|
-
* -
|
|
46
|
+
* - `node:test` support (`allowForKnownSafeCalls` for promise-returning functions)
|
|
42
47
|
* - Prettier compatibility (disables conflicting rules)
|
|
43
48
|
*
|
|
44
49
|
* Optional:
|
|
50
|
+
* - Vitest plugin for test files via `vitest: true`
|
|
45
51
|
* - Next.js rules (core-web-vitals + typescript) via `nextjs: true`
|
|
52
|
+
* - React Fast Refresh rule (included with `nextjs: true`)
|
|
46
53
|
* - Storybook rules (flat/recommended) via `storybook: true`
|
|
47
54
|
* - Tailwind CSS rules (better-tailwindcss/recommended) via `tailwindcss: "path/to/entry.css"`
|
|
48
55
|
*/
|
|
49
56
|
export declare function axkit(options?: Options): Promise<Linter.Config[]>;
|
|
57
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAM7C,MAAM,MAAM,OAAO,GAAG;IACpB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,KAAK,CAAC,OAAO,GAAE,OAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAiK3E"}
|
package/dist/index.js
CHANGED
|
@@ -4,8 +4,9 @@ import { includeIgnoreFile } from "@eslint/compat";
|
|
|
4
4
|
import eslintConfigPrettier from "eslint-config-prettier/flat";
|
|
5
5
|
import eslintPluginUnicorn from "eslint-plugin-unicorn";
|
|
6
6
|
import { importOptional } from "./import-optional.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { createBaseConfig } from "./base-config.js";
|
|
8
|
+
import { nodeTestConfig } from "./node-test-config.js";
|
|
9
|
+
import { createVitestConfig } from "./create-vitest-config.js";
|
|
9
10
|
/**
|
|
10
11
|
* Creates a complete ESLint flat config for TypeScript projects.
|
|
11
12
|
*
|
|
@@ -13,16 +14,18 @@ import { vitestConfig } from "./vitest-config.js";
|
|
|
13
14
|
* - ESLint recommended rules
|
|
14
15
|
* - TypeScript strict type checking
|
|
15
16
|
* - Unicorn plugin (recommended)
|
|
16
|
-
* -
|
|
17
|
+
* - `node:test` support (`allowForKnownSafeCalls` for promise-returning functions)
|
|
17
18
|
* - Prettier compatibility (disables conflicting rules)
|
|
18
19
|
*
|
|
19
20
|
* Optional:
|
|
21
|
+
* - Vitest plugin for test files via `vitest: true`
|
|
20
22
|
* - Next.js rules (core-web-vitals + typescript) via `nextjs: true`
|
|
23
|
+
* - React Fast Refresh rule (included with `nextjs: true`)
|
|
21
24
|
* - Storybook rules (flat/recommended) via `storybook: true`
|
|
22
25
|
* - Tailwind CSS rules (better-tailwindcss/recommended) via `tailwindcss: "path/to/entry.css"`
|
|
23
26
|
*/
|
|
24
27
|
export async function axkit(options = {}) {
|
|
25
|
-
const { gitignorePath, fastify, nextjs, storybook, tailwindcss } = options;
|
|
28
|
+
const { gitignorePath, vitest, fastify, nextjs, storybook, tailwindcss } = options;
|
|
26
29
|
const configs = [
|
|
27
30
|
{
|
|
28
31
|
name: "axkit/ignores",
|
|
@@ -35,14 +38,25 @@ export async function axkit(options = {}) {
|
|
|
35
38
|
}
|
|
36
39
|
// ── Next.js (before base so axkit's strict rules override) ─────────
|
|
37
40
|
if (nextjs) {
|
|
38
|
-
const [nextVitals, nextTs] = await Promise.all([
|
|
41
|
+
const [nextVitals, nextTs, reactRefreshPlugin] = await Promise.all([
|
|
39
42
|
importOptional("eslint-config-next/core-web-vitals"),
|
|
40
43
|
importOptional("eslint-config-next/typescript"),
|
|
44
|
+
importOptional("eslint-plugin-react-refresh"),
|
|
41
45
|
]);
|
|
42
|
-
configs.push(...nextVitals, ...nextTs
|
|
46
|
+
configs.push(...nextVitals, ...nextTs, {
|
|
47
|
+
name: "axkit/react-refresh",
|
|
48
|
+
files: ["**/*.{tsx,jsx}"],
|
|
49
|
+
plugins: { "react-refresh": reactRefreshPlugin },
|
|
50
|
+
rules: {
|
|
51
|
+
"react-refresh/only-export-components": [
|
|
52
|
+
"warn",
|
|
53
|
+
{ allowConstantExport: true },
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
});
|
|
43
57
|
}
|
|
44
58
|
// ── Core configs ───────────────────────────────────────────────────
|
|
45
|
-
configs.push(js.configs.recommended, ...tseslint.configs.strictTypeChecked,
|
|
59
|
+
configs.push(js.configs.recommended, ...tseslint.configs.strictTypeChecked, createBaseConfig(), eslintPluginUnicorn.configs.recommended,
|
|
46
60
|
// Unicorn rules that are off by default
|
|
47
61
|
{
|
|
48
62
|
name: "axkit/unicorn-extras",
|
|
@@ -58,7 +72,14 @@ export async function axkit(options = {}) {
|
|
|
58
72
|
name: "axkit/config-files",
|
|
59
73
|
files: ["*.config.{js,ts,mjs,mts}"],
|
|
60
74
|
...tseslint.configs.disableTypeChecked,
|
|
61
|
-
},
|
|
75
|
+
},
|
|
76
|
+
// node:test (always applied — harmless if not using node:test)
|
|
77
|
+
nodeTestConfig);
|
|
78
|
+
// ── Vitest (optional, requires @vitest/eslint-plugin) ──────────────
|
|
79
|
+
if (vitest) {
|
|
80
|
+
const vitestPlugin = await importOptional("@vitest/eslint-plugin");
|
|
81
|
+
configs.push(createVitestConfig(vitestPlugin));
|
|
82
|
+
}
|
|
62
83
|
// ── Fastify (disable conflicting rules) ────────────────────────────
|
|
63
84
|
if (fastify) {
|
|
64
85
|
configs.push({
|
|
@@ -123,3 +144,4 @@ export async function axkit(options = {}) {
|
|
|
123
144
|
configs.push(eslintConfigPrettier);
|
|
124
145
|
return configs;
|
|
125
146
|
}
|
|
147
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Linter } from "eslint";
|
|
2
|
+
/**
|
|
3
|
+
* Whitelists promise-returning `node:test` functions in the
|
|
4
|
+
* `no-floating-promises` rule via `allowForKnownSafeCalls`.
|
|
5
|
+
*
|
|
6
|
+
* Always applied — harmless if not using `node:test`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const nodeTestConfig: Linter.Config;
|
|
9
|
+
//# sourceMappingURL=node-test-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-test-config.d.ts","sourceRoot":"","sources":["../src/node-test-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAoBnC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whitelists promise-returning `node:test` functions in the
|
|
3
|
+
* `no-floating-promises` rule via `allowForKnownSafeCalls`.
|
|
4
|
+
*
|
|
5
|
+
* Always applied — harmless if not using `node:test`.
|
|
6
|
+
*/
|
|
7
|
+
export const nodeTestConfig = {
|
|
8
|
+
name: "axkit/node-test",
|
|
9
|
+
files: [
|
|
10
|
+
"**/*.{test,spec}.{ts,tsx,js,mjs,cjs,mts,cts}",
|
|
11
|
+
"tests/**/*.{ts,tsx,js,mjs,cjs,mts,cts}",
|
|
12
|
+
],
|
|
13
|
+
rules: {
|
|
14
|
+
"@typescript-eslint/no-floating-promises": [
|
|
15
|
+
"error",
|
|
16
|
+
{
|
|
17
|
+
allowForKnownSafeCalls: [
|
|
18
|
+
{
|
|
19
|
+
from: "package",
|
|
20
|
+
package: "node:test",
|
|
21
|
+
name: ["describe", "it", "test", "suite", "todo", "skip", "only"],
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=node-test-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-test-config.js","sourceRoot":"","sources":["../src/node-test-config.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAkB;IAC3C,IAAI,EAAE,iBAAiB;IACvB,KAAK,EAAE;QACL,8CAA8C;QAC9C,wCAAwC;KACzC;IACD,KAAK,EAAE;QACL,yCAAyC,EAAE;YACzC,OAAO;YACP;gBACE,sBAAsB,EAAE;oBACtB;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,WAAW;wBACpB,IAAI,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;qBAClE;iBACF;aACF;SACF;KACF;CACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
{
|
|
2
|
+
"scripts": {
|
|
3
|
+
"prepack": "pnpm run rebuild",
|
|
4
|
+
"prepare": "git config core.hooksPath .githooks",
|
|
5
|
+
"build": "tsc -p tsconfig.app.json",
|
|
6
|
+
"clean": "rm -rf dist *.tsbuildinfo",
|
|
7
|
+
"format": "prettier --write .",
|
|
8
|
+
"format:check": "prettier --check .",
|
|
9
|
+
"fta": "fta-check",
|
|
10
|
+
"knip": "knip",
|
|
11
|
+
"lint": "eslint",
|
|
12
|
+
"rebuild": "pnpm run clean && pnpm run build",
|
|
13
|
+
"test": "node --test src/**/*.test.ts",
|
|
14
|
+
"typecheck": "tsc -b --noEmit"
|
|
15
|
+
},
|
|
2
16
|
"name": "eslint-config-axkit",
|
|
3
17
|
"author": "Łukasz Jerciński",
|
|
4
18
|
"license": "MIT",
|
|
5
|
-
"version": "1.
|
|
6
|
-
"description": "Reusable ESLint flat config for TypeScript + Node.js projects with strict type checking, Prettier,
|
|
19
|
+
"version": "1.6.1",
|
|
20
|
+
"description": "Reusable ESLint flat config for TypeScript + Node.js projects with strict type checking, Prettier, and Unicorn",
|
|
7
21
|
"repository": {
|
|
8
22
|
"type": "git",
|
|
9
23
|
"url": "git+https://github.com/Jercik/eslint-config-axkit.git"
|
|
@@ -26,22 +40,6 @@
|
|
|
26
40
|
"README.md",
|
|
27
41
|
"LICENSE"
|
|
28
42
|
],
|
|
29
|
-
"scripts": {
|
|
30
|
-
"prepare": "git config core.hooksPath .githooks",
|
|
31
|
-
"prepublishOnly": "pnpm run rebuild",
|
|
32
|
-
"build": "tsc -p tsconfig.app.json",
|
|
33
|
-
"clean": "rm -rf dist *.tsbuildinfo",
|
|
34
|
-
"format": "prettier --write .",
|
|
35
|
-
"format:check": "prettier --check .",
|
|
36
|
-
"fta": "fta-check",
|
|
37
|
-
"knip": "knip",
|
|
38
|
-
"lint": "eslint",
|
|
39
|
-
"rebuild": "pnpm run clean && pnpm run build",
|
|
40
|
-
"test": "vitest run",
|
|
41
|
-
"test:coverage": "vitest run --coverage",
|
|
42
|
-
"test:watch": "vitest",
|
|
43
|
-
"typecheck": "tsc -b --noEmit"
|
|
44
|
-
},
|
|
45
43
|
"keywords": [
|
|
46
44
|
"eslint",
|
|
47
45
|
"eslintconfig",
|
|
@@ -50,17 +48,18 @@
|
|
|
50
48
|
"typescript",
|
|
51
49
|
"prettier",
|
|
52
50
|
"unicorn",
|
|
53
|
-
"vitest",
|
|
54
51
|
"axkit"
|
|
55
52
|
],
|
|
56
|
-
"packageManager": "pnpm@10.
|
|
53
|
+
"packageManager": "pnpm@10.32.1",
|
|
57
54
|
"engines": {
|
|
58
|
-
"node": ">=22.
|
|
55
|
+
"node": ">=22.19.0"
|
|
59
56
|
},
|
|
60
57
|
"peerDependencies": {
|
|
58
|
+
"@vitest/eslint-plugin": ">=1",
|
|
61
59
|
"eslint": ">=10",
|
|
62
60
|
"eslint-config-next": ">=16",
|
|
63
61
|
"eslint-plugin-better-tailwindcss": ">=4",
|
|
62
|
+
"eslint-plugin-react-refresh": ">=0.4",
|
|
64
63
|
"eslint-plugin-storybook": ">=10"
|
|
65
64
|
},
|
|
66
65
|
"peerDependenciesMeta": {
|
|
@@ -70,30 +69,33 @@
|
|
|
70
69
|
"eslint-plugin-better-tailwindcss": {
|
|
71
70
|
"optional": true
|
|
72
71
|
},
|
|
72
|
+
"eslint-plugin-react-refresh": {
|
|
73
|
+
"optional": true
|
|
74
|
+
},
|
|
73
75
|
"eslint-plugin-storybook": {
|
|
74
76
|
"optional": true
|
|
77
|
+
},
|
|
78
|
+
"@vitest/eslint-plugin": {
|
|
79
|
+
"optional": true
|
|
75
80
|
}
|
|
76
81
|
},
|
|
77
82
|
"dependencies": {
|
|
78
|
-
"@eslint/compat": "^2.0.
|
|
83
|
+
"@eslint/compat": "^2.0.4",
|
|
79
84
|
"@eslint/js": "^10.0.1",
|
|
80
|
-
"@vitest/eslint-plugin": "^1.6.9",
|
|
81
85
|
"eslint-config-prettier": "^10.1.8",
|
|
82
|
-
"eslint-plugin-unicorn": "^
|
|
86
|
+
"eslint-plugin-unicorn": "^64.0.0",
|
|
83
87
|
"globals": "^17.4.0",
|
|
84
|
-
"typescript-eslint": "^8.
|
|
88
|
+
"typescript-eslint": "^8.58.1"
|
|
85
89
|
},
|
|
86
90
|
"devDependencies": {
|
|
87
91
|
"@total-typescript/ts-reset": "^0.6.1",
|
|
88
|
-
"@types/node": "^25.
|
|
89
|
-
"
|
|
90
|
-
"eslint": "^10.0.3",
|
|
92
|
+
"@types/node": "^25.5.2",
|
|
93
|
+
"eslint": "^10.2.0",
|
|
91
94
|
"fta-check": "^1.5.1",
|
|
92
95
|
"fta-cli": "^3.0.0",
|
|
93
|
-
"knip": "^
|
|
96
|
+
"knip": "^6.3.0",
|
|
94
97
|
"prettier": "3.8.1",
|
|
95
98
|
"semantic-release": "^25.0.3",
|
|
96
|
-
"typescript": "^
|
|
97
|
-
"vitest": "^4.0.18"
|
|
99
|
+
"typescript": "^6.0.2"
|
|
98
100
|
}
|
|
99
101
|
}
|
package/dist/vitest-config.d.ts
DELETED
package/dist/vitest-config.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import vitest from "@vitest/eslint-plugin";
|
|
2
|
-
export const vitestConfig = {
|
|
3
|
-
name: "axkit/vitest",
|
|
4
|
-
files: [
|
|
5
|
-
"**/*.{test,spec}.{ts,tsx,js,mjs,cjs,mts,cts}",
|
|
6
|
-
"tests/**/*.{ts,tsx,js,mjs,cjs,mts,cts}",
|
|
7
|
-
],
|
|
8
|
-
plugins: { vitest },
|
|
9
|
-
rules: {
|
|
10
|
-
...vitest.configs.recommended.rules,
|
|
11
|
-
// Ensure expect.poll() and expect.element() are awaited
|
|
12
|
-
"vitest/require-awaited-expect-poll": "error",
|
|
13
|
-
// Keep vi.mock() and other hoisted APIs at the top of files
|
|
14
|
-
"vitest/hoisted-apis-on-top": "warn",
|
|
15
|
-
// Prefer toHaveBeenCalledTimes() matcher
|
|
16
|
-
"vitest/prefer-to-have-been-called-times": "warn",
|
|
17
|
-
// Prefer mockResolvedValue() over mockImplementation(() => Promise.resolve())
|
|
18
|
-
"vitest/prefer-mock-promise-shorthand": "warn",
|
|
19
|
-
// Prefer expectTypeOf() for type testing
|
|
20
|
-
"vitest/prefer-expect-type-of": "warn",
|
|
21
|
-
// Enforce consistent use of .each vs .for for parameterized tests
|
|
22
|
-
"vitest/consistent-each-for": "warn",
|
|
23
|
-
// Keep hooks (beforeEach, afterEach, etc.) at the top of describe blocks
|
|
24
|
-
"vitest/prefer-hooks-on-top": "warn",
|
|
25
|
-
// ===== Test Logic Errors =====
|
|
26
|
-
// No conditionals (if/else) inside test bodies - tests should be deterministic
|
|
27
|
-
"vitest/no-conditional-in-test": "error",
|
|
28
|
-
// No conditionally defined tests - tests should always run
|
|
29
|
-
"vitest/no-conditional-tests": "error",
|
|
30
|
-
// No return statements in tests - just execute assertions
|
|
31
|
-
"vitest/no-test-return-statement": "warn",
|
|
32
|
-
// No duplicate lifecycle hooks
|
|
33
|
-
"vitest/no-duplicate-hooks": "warn",
|
|
34
|
-
// ===== Better Matchers (auto-fixable) =====
|
|
35
|
-
// Use toBe() for primitives (strict equality)
|
|
36
|
-
"vitest/prefer-to-be": "warn",
|
|
37
|
-
// Use toHaveLength() instead of expect(arr.length).toBe()
|
|
38
|
-
"vitest/prefer-to-have-length": "warn",
|
|
39
|
-
// Use toContain() instead of expect(arr.includes()).toBe(true)
|
|
40
|
-
"vitest/prefer-to-contain": "warn",
|
|
41
|
-
// Use toBeGreaterThan(), toBeLessThan(), etc.
|
|
42
|
-
"vitest/prefer-comparison-matcher": "warn",
|
|
43
|
-
// Use dedicated equality matchers
|
|
44
|
-
"vitest/prefer-equality-matcher": "warn",
|
|
45
|
-
// ===== Best Practices =====
|
|
46
|
-
// Use vi.spyOn() instead of direct property assignment
|
|
47
|
-
"vitest/prefer-spy-on": "warn",
|
|
48
|
-
// Use test.todo() for empty/placeholder tests
|
|
49
|
-
"vitest/prefer-todo": "warn",
|
|
50
|
-
// Use expect().resolves instead of expect(await promise)
|
|
51
|
-
"vitest/prefer-expect-resolves": "warn",
|
|
52
|
-
// No deprecated alias methods (toBeCalled → toHaveBeenCalled)
|
|
53
|
-
"vitest/no-alias-methods": "warn",
|
|
54
|
-
// Use vi.mocked() instead of type casting
|
|
55
|
-
"vitest/prefer-vi-mocked": "warn",
|
|
56
|
-
// Use .only/.skip instead of f/x prefixes
|
|
57
|
-
"vitest/no-test-prefixes": "warn",
|
|
58
|
-
},
|
|
59
|
-
languageOptions: {
|
|
60
|
-
globals: { ...vitest.environments.env.globals },
|
|
61
|
-
},
|
|
62
|
-
};
|