@knapsack/eslint-config-starter 5.0.0--canary.6593.4738696.0 β†’ 5.0.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/CHANGELOG.md CHANGED
@@ -1,3 +1,145 @@
1
+ # v4.89.8 (Fri Feb 20 2026)
2
+
3
+ ### Release Notes
4
+
5
+ #### KSP-7685: Synthetic Data for Conflict Enrichment/Resolution testing ([#7154](https://github.com/knapsack-labs/app-monorepo/pull/7154))
6
+
7
+ * **Documentation**
8
+ * Added synthetic multi-source test fixtures including component documentation, design tokens, and brand guidelines for comprehensive testing coverage.
9
+
10
+ <!-- end of auto-generated comment: release notes by coderabbit.ai -->
11
+
12
+ ---
13
+
14
+ #### πŸ› Bug Fix
15
+
16
+ - merge latest in ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
17
+ - Formated pkgs ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
18
+ - Merge branch 'latest' into sxa/KSP-7037-tests-v2 ([@sxalexander](https://github.com/sxalexander))
19
+ - replaced removed @typescript-eslint/ban-types with v8 replacement rules ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
20
+ - Fixed Lint issue on config starter ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
21
+ - Migrated ESLint config to flat config format (ESLint 9) ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
22
+
23
+ #### 🏠 Internal
24
+
25
+ - KSP-7685: Synthetic Data for Conflict Enrichment/Resolution testing [#7154](https://github.com/knapsack-labs/app-monorepo/pull/7154) ([@sxalexander](https://github.com/sxalexander))
26
+ - KSP-5524 Migrated ESLint config to flat config format (ESLint 9) [#7162](https://github.com/knapsack-labs/app-monorepo/pull/7162) ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
27
+
28
+ #### Authors: 2
29
+
30
+ - [@EmmanuelVelez](https://github.com/EmmanuelVelez)
31
+ - Sam Alexander ([@sxalexander](https://github.com/sxalexander))
32
+
33
+ ---
34
+
35
+ # v4.89.7 (Fri Feb 06 2026)
36
+
37
+ #### πŸ› Bug Fix
38
+
39
+ - Merge branch 'latest' into feature/ksp-6555-remove-app-client-watchers-for-files-in-data-directory ([@EvanLovely](https://github.com/EvanLovely))
40
+ - resolved some of react-hooks/set-state-in-effect lint errors and enable rule as error ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
41
+ - Merge branch 'latest' into feature/ksp-6555-remove-app-client-watchers-for-files-in-data-directory ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
42
+
43
+ #### 🏠 Internal
44
+
45
+ - KSP-6106 Added consistent-type-imports rule with inline type syntax [#7128](https://github.com/knapsack-labs/app-monorepo/pull/7128) ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
46
+ - KSP-7692: expand server actions body size limit [#7097](https://github.com/knapsack-labs/app-monorepo/pull/7097) ([@illepic](https://github.com/illepic))
47
+ - KSP-7623 resolved some of react-hooks/set-state-in-effect lint errors and enab… [#7077](https://github.com/knapsack-labs/app-monorepo/pull/7077) ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
48
+
49
+ #### Authors: 3
50
+
51
+ - [@EmmanuelVelez](https://github.com/EmmanuelVelez)
52
+ - Christopher Bloom ([@illepic](https://github.com/illepic))
53
+ - Evan Lovely ([@EvanLovely](https://github.com/EvanLovely))
54
+
55
+ ---
56
+
57
+ # v4.89.6 (Fri Jan 09 2026)
58
+
59
+ #### 🏠 Internal
60
+
61
+ - upgrade react eslint plugin [#7067](https://github.com/knapsack-labs/app-monorepo/pull/7067) ([@EvanLovely](https://github.com/EvanLovely))
62
+
63
+ #### Authors: 1
64
+
65
+ - Evan Lovely ([@EvanLovely](https://github.com/EvanLovely))
66
+
67
+ ---
68
+
69
+ # v4.89.4 (Mon Jan 05 2026)
70
+
71
+ #### 🏠 Internal
72
+
73
+ - KSP-6086 normalize error and log metadata for api domains [#6997](https://github.com/knapsack-labs/app-monorepo/pull/6997) ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
74
+
75
+ #### Authors: 1
76
+
77
+ - [@EmmanuelVelez](https://github.com/EmmanuelVelez)
78
+
79
+ ---
80
+
81
+ # v4.89.3 (Thu Dec 11 2025)
82
+
83
+ #### πŸ› Bug Fix
84
+
85
+ - KSP-6536 Fixed align token metrics counting with UI logic for variables and collections [#6778](https://github.com/knapsack-labs/app-monorepo/pull/6778) ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
86
+ - Merge branch 'latest' into feature/ksp-6536-metrics-not-computing-tokens-and-variables-correctly ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
87
+ - Merge remote-tracking branch 'origin/feature/ksp-6536-metrics-not-computing-tokens-and-variables-correctly' into feature/ksp-6536-metrics-not-computing-tokens-and-variables-correctly ([@EmmanuelVelez](https://github.com/EmmanuelVelez))
88
+
89
+ #### Authors: 1
90
+
91
+ - [@EmmanuelVelez](https://github.com/EmmanuelVelez)
92
+
93
+ ---
94
+
95
+ # v4.89.1 (Wed Dec 10 2025)
96
+
97
+ #### πŸ› Bug Fix
98
+
99
+ - Merge remote-tracking branch 'origin/latest' into KSP-6900_mcp_onboarding_pages ([@brittanysmart](https://github.com/brittanysmart))
100
+
101
+ #### Authors: 1
102
+
103
+ - Brittany Smart ([@brittanysmart](https://github.com/brittanysmart))
104
+
105
+ ---
106
+
107
+ # v4.87.9 (Thu Nov 20 2025)
108
+
109
+ #### 🏠 Internal
110
+
111
+ - fix(deps): update dependency @types/node to ^20.19.25 [#6803](https://github.com/knapsack-labs/app-monorepo/pull/6803) ([@renovate[bot]](https://github.com/renovate[bot]))
112
+
113
+ #### Authors: 1
114
+
115
+ - [@renovate[bot]](https://github.com/renovate[bot])
116
+
117
+ ---
118
+
119
+ # v4.87.7 (Mon Nov 10 2025)
120
+
121
+ #### 🏠 Internal
122
+
123
+ - fix(deps): update typescript [#6863](https://github.com/knapsack-labs/app-monorepo/pull/6863) ([@renovate[bot]](https://github.com/renovate[bot]))
124
+
125
+ #### Authors: 1
126
+
127
+ - [@renovate[bot]](https://github.com/renovate[bot])
128
+
129
+ ---
130
+
131
+ # v4.87.6 (Wed Nov 05 2025)
132
+
133
+ #### 🏠 Internal
134
+
135
+ - Add comprehensive testing for remaining frameworks and MUI lib [#6876](https://github.com/knapsack-labs/app-monorepo/pull/6876) ([@mabry1985](https://github.com/mabry1985))
136
+
137
+ #### Authors: 1
138
+
139
+ - Josh Mabry ([@mabry1985](https://github.com/mabry1985))
140
+
141
+ ---
142
+
1
143
  # v4.87.4 (Fri Oct 31 2025)
2
144
 
3
145
  #### 🏠 Internal
@@ -0,0 +1,25 @@
1
+ /**
2
+ * ESM-specific ESLint configuration
3
+ */
4
+ import unicorn from 'eslint-plugin-unicorn';
5
+
6
+ /**
7
+ * ESM ESLint configuration
8
+ * @returns {import('eslint').Linter.Config[]}
9
+ */
10
+ export function createEsmConfig() {
11
+ return [
12
+ {
13
+ plugins: {
14
+ unicorn,
15
+ },
16
+ rules: {
17
+ 'unicorn/prefer-module': 'error',
18
+ 'unicorn/prefer-node-protocol': 'error',
19
+ 'unicorn/prefer-top-level-await': 'error',
20
+ },
21
+ },
22
+ ];
23
+ }
24
+
25
+ export default createEsmConfig();
@@ -0,0 +1,77 @@
1
+ /**
2
+ * React-specific ESLint configuration
3
+ */
4
+ import react from 'eslint-plugin-react';
5
+ import reactHooks from 'eslint-plugin-react-hooks';
6
+ import jsxA11y from 'eslint-plugin-jsx-a11y';
7
+
8
+ /**
9
+ * React ESLint configuration
10
+ * @returns {import('eslint').Linter.Config[]}
11
+ */
12
+ export function createReactConfig() {
13
+ return [
14
+ // React recommended config
15
+ react.configs.flat.recommended,
16
+ react.configs.flat['jsx-runtime'],
17
+
18
+ // React Hooks
19
+ reactHooks.configs['recommended-latest'],
20
+
21
+ // JSX Accessibility
22
+ jsxA11y.flatConfigs.recommended,
23
+
24
+ // Custom React rules
25
+ {
26
+ plugins: {
27
+ react,
28
+ 'react-hooks': reactHooks,
29
+ 'jsx-a11y': jsxA11y,
30
+ },
31
+
32
+ settings: {
33
+ react: {
34
+ version: 'detect',
35
+ },
36
+ },
37
+
38
+ rules: {
39
+ // JSX A11y
40
+ 'jsx-a11y/anchor-is-valid': ['warn', { aspects: ['invalidHref'] }],
41
+ 'jsx-a11y/href-no-hash': 'off',
42
+ 'jsx-a11y/control-has-associated-label': 'off',
43
+
44
+ // React
45
+ 'react/boolean-prop-naming': 'off',
46
+ 'react/destructuring-assignment': 'off',
47
+ 'react/forbid-prop-types': ['error', { forbid: ['any', 'array'] }],
48
+ 'react/no-unknown-property': 'off',
49
+ 'react/prop-types': 'off',
50
+ 'react/function-component-definition': 'off',
51
+ 'react/no-unstable-nested-components': [
52
+ 'error',
53
+ { allowAsProps: true },
54
+ ],
55
+ 'react/jsx-key': 'error',
56
+ 'react/no-array-index-key': 'error',
57
+ 'react/no-danger': 'off',
58
+ 'react/jsx-props-no-spreading': 'off',
59
+ 'react/sort-comp': 'off',
60
+ 'react/static-property-placement': ['off', 'static public field'],
61
+ 'react/require-extension': 'off',
62
+ 'react/jsx-filename-extension': [
63
+ 'error',
64
+ { extensions: ['.tsx', '.jsx'] },
65
+ ],
66
+ 'react/require-default-props': 'off',
67
+ 'react/no-unused-prop-types': 'off',
68
+
69
+ // React Hooks
70
+ 'react-hooks/rules-of-hooks': 'error',
71
+ 'react-hooks/exhaustive-deps': 'error',
72
+ },
73
+ },
74
+ ];
75
+ }
76
+
77
+ export default createReactConfig();
@@ -3,7 +3,7 @@ export declare const eslintConfigStarterCreator: import("@knapsack/creator-utils
3
3
  type: "boolean";
4
4
  title: string;
5
5
  };
6
- hasAva: {
6
+ hasEsm: {
7
7
  type: "boolean";
8
8
  title: string;
9
9
  };
@@ -21,7 +21,7 @@ export declare const eslintConfigStarterCreator: import("@knapsack/creator-utils
21
21
  type: "boolean";
22
22
  title: string;
23
23
  };
24
- hasAva: {
24
+ hasEsm: {
25
25
  type: "boolean";
26
26
  title: string;
27
27
  };
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-config-starter-creator.d.ts","sourceRoot":"","sources":["../src/eslint-config-starter-creator.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+GrC,CAAC"}
1
+ {"version":3,"file":"eslint-config-starter-creator.d.ts","sourceRoot":"","sources":["../src/eslint-config-starter-creator.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8ErC,CAAC"}
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.eslintConfigStarterCreator = void 0;
4
4
  const creator_utils_1 = require("@knapsack/creator-utils");
5
5
  const creator_1 = require("@knapsack/prettier-config/creator");
6
- const path_1 = require("path");
7
6
  const { pkg } = (0, creator_utils_1.findUpPkgJson)(__dirname);
8
7
  const pkgName = pkg.name;
9
8
  if (typeof pkgName !== 'string') {
@@ -14,11 +13,11 @@ exports.eslintConfigStarterCreator = (0, creator_utils_1.createCreator)({
14
13
  getQuestions: async () => ({
15
14
  hasReact: {
16
15
  type: 'boolean',
17
- title: 'Using React?',
16
+ title: 'Using React? (Note: Add package path to root eslint.config.mjs reactPackages array)',
18
17
  },
19
- hasAva: {
18
+ hasEsm: {
20
19
  type: 'boolean',
21
- title: 'Using Ava for testing?',
20
+ title: 'Using ESM? (Note: Add package path to root eslint.config.mjs esmPackages array)',
22
21
  },
23
22
  addNpmScript: {
24
23
  type: 'boolean',
@@ -30,67 +29,33 @@ exports.eslintConfigStarterCreator = (0, creator_utils_1.createCreator)({
30
29
  default: false,
31
30
  },
32
31
  }),
33
- getTasks: async ({ answers: { hasAva, hasReact, addNpmScript, addIgnore }, config, }) => {
32
+ getTasks: async ({ answers: { addNpmScript, addIgnore }, config }) => {
34
33
  const { dest } = config;
35
- const configs = [
36
- hasReact && '@knapsack/eslint-config-starter/react',
37
- hasAva && '@knapsack/eslint-config-starter/ava',
38
- '@knapsack/eslint-config-starter',
39
- ].filter(Boolean);
40
34
  return [
41
35
  {
42
- title: 'Add .eslintrc.js',
43
- skip: (0, creator_utils_1.hasFileUp)({
44
- cwd: dest,
45
- file: [
46
- '.eslintrc.js',
47
- '.eslintrc.cjs',
48
- '.eslintrc.yaml',
49
- '.eslintrc.yml',
50
- '.eslintrc.json',
51
- '.eslintrc',
52
- ],
53
- }) && 'Found pre-existing file',
36
+ title: 'Note: ESLint uses flat config',
54
37
  task: async (ctx, task) => {
55
- return creator_utils_1.tasks.addFile({
56
- destination: (0, path_1.join)(dest, '.eslintrc.cjs'),
57
- handlePriorFile: 'skip',
58
- contents: `
59
- module.exports = {
60
- extends: [${configs.map((c) => `'${c}'`).join(', ')}],
61
- parserOptions: { tsconfigRootDir: __dirname },
62
- ignorePatterns: [],
63
- rules: {},
64
- };
65
- `,
66
- });
67
- },
68
- },
69
- {
70
- title: 'Add .eslintignore',
71
- skip: (0, creator_utils_1.hasFileUp)({ file: '.eslintignore' }) && 'Found pre-existing file',
72
- task: async (ctx, task) => {
73
- task.output = await creator_utils_1.tasks.addFile({
74
- destination: (0, path_1.join)(dest, '.eslintignore'),
75
- contents: ['dist'],
76
- handlePriorFile: 'skip',
77
- });
38
+ task.output = `
39
+ ESLint is configured via the root eslint.config.mjs file.
40
+ No per-package config needed. If this package needs special rules:
41
+ 1. Add the package path to the appropriate arrays in eslint.config.mjs:
42
+ - reactPackages: for React packages
43
+ - esmPackages: for ESM packages
44
+ 2. Add custom overrides in the "PACKAGE-SPECIFIC OVERRIDES" section if needed.
45
+ `.trim();
78
46
  },
79
47
  },
80
48
  {
81
49
  title: 'Update package.json with eslint',
82
- task: async () => {
83
- var _a;
84
- return creator_utils_1.tasks.updatePkgJson({
85
- dir: dest,
86
- pkg: {
87
- devDependencies: {
88
- [pkgName]: pkg.version,
89
- eslint: (_a = pkg.dependencies) === null || _a === void 0 ? void 0 : _a.eslint,
90
- },
50
+ task: async () => creator_utils_1.tasks.updatePkgJson({
51
+ dir: dest,
52
+ pkg: {
53
+ devDependencies: {
54
+ [pkgName]: pkg.version,
55
+ eslint: pkg.dependencies?.eslint,
91
56
  },
92
- });
93
- },
57
+ },
58
+ }),
94
59
  },
95
60
  {
96
61
  title: 'Adding lint npm script to package.json',
@@ -99,7 +64,7 @@ module.exports = {
99
64
  dir: dest,
100
65
  pkg: {
101
66
  scripts: {
102
- lint: 'eslint ./',
67
+ lint: 'eslint .',
103
68
  },
104
69
  },
105
70
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-config-starter-creator.js","sourceRoot":"","sources":["../src/eslint-config-starter-creator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eslint-config-starter-creator.js","sourceRoot":"","sources":["../src/eslint-config-starter-creator.ts"],"names":[],"mappings":";;;AAAA,2DAA8E;AAC9E,+DAA0E;AAE1E,MAAM,EAAE,GAAG,EAAE,GAAG,IAAA,6BAAa,EAAC,SAAS,CAAC,CAAC;AACzC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC;AACzB,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;IAChC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;AAC9C,CAAC;AAEY,QAAA,0BAA0B,GAAG,IAAA,6BAAa,EAAC;IACtD,EAAE,EAAE,uBAAuB;IAC3B,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QACzB,QAAQ,EAAE;YACR,IAAI,EAAE,SAAS;YACf,KAAK,EACH,qFAAqF;SACxF;QACD,MAAM,EAAE;YACN,IAAI,EAAE,SAAS;YACf,KAAK,EACH,iFAAiF;SACpF;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,kCAAkC;SAC1C;QACD,SAAS,EAAE;YACT,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,2BAA2B;YAClC,OAAO,EAAE,KAAK;SACf;KACF,CAAC;IACF,QAAQ,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;QACxB,OAAO;YACL;gBACE,KAAK,EAAE,+BAA+B;gBACtC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;oBACxB,IAAI,CAAC,MAAM,GAAG;;;;;;;WAOb,CAAC,IAAI,EAAE,CAAC;gBACX,CAAC;aACF;YACD;gBACE,KAAK,EAAE,iCAAiC;gBACxC,IAAI,EAAE,KAAK,IAAI,EAAE,CACf,qBAAK,CAAC,aAAa,CAAC;oBAClB,GAAG,EAAE,IAAI;oBACT,GAAG,EAAE;wBACH,eAAe,EAAE;4BACf,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,OAAO;4BACtB,MAAM,EAAE,GAAG,CAAC,YAAY,EAAE,MAAM;yBACjC;qBACF;iBACF,CAAC;aACL;YACD;gBACE,KAAK,EAAE,wCAAwC;gBAC/C,IAAI,EAAE,CAAC,YAAY;gBACnB,IAAI,EAAE,KAAK,IAAI,EAAE,CACf,qBAAK,CAAC,aAAa,CAAC;oBAClB,GAAG,EAAE,IAAI;oBACT,GAAG,EAAE;wBACH,OAAO,EAAE;4BACP,IAAI,EAAE,UAAU;yBACjB;qBACF;iBACF,CAAC;aACL;YACD;gBACE,KAAK,EAAE,iBAAiB;gBACxB,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;oBACtB,OAAO,qBAAK,CAAC,aAAa,CAAC;wBACzB,OAAO,EAAE,+BAAqB;wBAC9B,MAAM;wBACN,IAAI;wBACJ,YAAY,EAAE,EAAE,SAAS,EAAE;qBAC5B,CAAC,CAAC;gBACL,CAAC;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -56,6 +56,16 @@ module.exports = {
56
56
  files: ['*.ts', '*.tsx', '*.mts'],
57
57
  extends: ['plugin:@typescript-eslint/recommended'],
58
58
  rules: {
59
+ // Enforce type imports to keep JS bundles small
60
+ // Uses inline style: `import { type Thing }` instead of `import type { Thing }`
61
+ // This reduces merge conflicts when adding non-type imports to the same statement
62
+ '@typescript-eslint/consistent-type-imports': [
63
+ 'error',
64
+ {
65
+ prefer: 'type-imports',
66
+ fixStyle: 'inline-type-imports',
67
+ },
68
+ ],
59
69
  // @TODO: KSP-4627: re-enable 'jsx-a11y/control-has-associated-label'
60
70
  'jsx-a11y/control-has-associated-label': [0],
61
71
  '@typescript-eslint/no-explicit-any': [1],
@@ -0,0 +1,227 @@
1
+ /**
2
+ * @knapsack/eslint-config-starter - ESLint Flat Config
3
+ *
4
+ * This is the main ESLint configuration for the Knapsack monorepo.
5
+ * It uses the new flat config format introduced in ESLint 9.
6
+ *
7
+ * @see https://eslint.org/docs/latest/use/configure/configuration-files
8
+ */
9
+ import js from '@eslint/js';
10
+ import tseslint from 'typescript-eslint';
11
+ import prettier from 'eslint-config-prettier';
12
+ import prettierPlugin from 'eslint-plugin-prettier';
13
+ import jsdoc from 'eslint-plugin-jsdoc';
14
+ import promise from 'eslint-plugin-promise';
15
+ import unusedImports from 'eslint-plugin-unused-imports';
16
+ import importX from 'eslint-plugin-import-x';
17
+ import globals from 'globals';
18
+
19
+ /**
20
+ * Base ESLint configuration for the Knapsack monorepo
21
+ * @param {object} options - Configuration options
22
+ * @param {string} [options.tsconfigRootDir] - Root directory for TypeScript config
23
+ * @returns {import('eslint').Linter.Config[]}
24
+ */
25
+ export function createBaseConfig({ tsconfigRootDir } = {}) {
26
+ return [
27
+ // Global ignores
28
+ {
29
+ ignores: [
30
+ '**/node_modules/**',
31
+ '**/dist/**',
32
+ '**/*.log',
33
+ '**/Caches/typescript/**',
34
+ '**/temp/**',
35
+ '**/.rush/**',
36
+ '**/coverage/**',
37
+ '**/.next/**',
38
+ '**/build/**',
39
+ ],
40
+ },
41
+
42
+ // Base JavaScript recommended rules
43
+ js.configs.recommended,
44
+
45
+ // TypeScript ESLint recommended rules
46
+ ...tseslint.configs.recommended,
47
+
48
+ // Prettier config (disables conflicting rules)
49
+ prettier,
50
+
51
+ // Main configuration for all files
52
+ {
53
+ plugins: {
54
+ prettier: prettierPlugin,
55
+ jsdoc,
56
+ promise,
57
+ 'unused-imports': unusedImports,
58
+ 'import-x': importX,
59
+ },
60
+
61
+ languageOptions: {
62
+ ecmaVersion: 'latest',
63
+ sourceType: 'module',
64
+ globals: {
65
+ ...globals.browser,
66
+ ...globals.node,
67
+ document: true,
68
+ window: true,
69
+ fetch: true,
70
+ },
71
+ parserOptions: {
72
+ ecmaFeatures: {
73
+ jsx: true,
74
+ },
75
+ },
76
+ },
77
+
78
+ settings: {
79
+ 'import-x/resolver': {
80
+ node: {
81
+ extensions: ['.js', '.jsx', '.ts', '.tsx'],
82
+ },
83
+ typescript: tsconfigRootDir ? { project: tsconfigRootDir } : {},
84
+ },
85
+ 'import-x/parsers': {
86
+ '@typescript-eslint/parser': ['.ts', '.tsx'],
87
+ },
88
+ },
89
+
90
+ rules: {
91
+ // Prettier
92
+ 'prettier/prettier': 'error',
93
+
94
+ // Unused imports
95
+ 'unused-imports/no-unused-imports': 'error',
96
+ 'unused-imports/no-unused-vars': [
97
+ 'warn',
98
+ {
99
+ vars: 'all',
100
+ varsIgnorePattern: '^_',
101
+ args: 'after-used',
102
+ argsIgnorePattern: '^_',
103
+ },
104
+ ],
105
+ 'no-unused-vars': 'off',
106
+
107
+ // General rules (from airbnb/base equivalent)
108
+ 'no-continue': 'off',
109
+ 'no-use-before-define': 'off',
110
+ 'no-restricted-syntax': 'off',
111
+ 'no-return-await': 'off',
112
+ 'arrow-body-style': 'off',
113
+ 'no-await-in-loop': 'off',
114
+ 'no-constant-condition': ['warn', { checkLoops: false }],
115
+ 'consistent-return': 'off',
116
+ camelcase: 'off',
117
+ 'no-unreachable': 'off',
118
+ 'no-console': 'off',
119
+ 'default-case': 'off',
120
+ 'no-inner-declarations': 'off',
121
+ 'no-param-reassign': ['warn', { props: false }],
122
+ 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }],
123
+ 'no-useless-constructor': 'off',
124
+ 'no-promise-executor-return': 'off',
125
+ 'no-underscore-dangle': 'off',
126
+ 'prefer-arrow-callback': 'off',
127
+ strict: 'off',
128
+
129
+ // JSDoc
130
+ 'jsdoc/check-types': 'error',
131
+
132
+ // Import rules
133
+ 'import-x/no-extraneous-dependencies': 'off',
134
+ 'import-x/prefer-default-export': 'off',
135
+ 'import-x/dynamic-import-chunkname': 'off',
136
+ 'import-x/no-dynamic-require': 'off',
137
+ 'import-x/extensions': 'off',
138
+ 'import-x/no-unresolved': 'error',
139
+
140
+ // Restricted imports
141
+ 'no-restricted-imports': [
142
+ 'error',
143
+ {
144
+ paths: [
145
+ {
146
+ name: 'moment',
147
+ message:
148
+ 'Please use the data-fns package (https://date-fns.org/) instead of the moment package to manipulate time and dates.',
149
+ },
150
+ {
151
+ name: 'lodash',
152
+ message:
153
+ "Import lodash methods from default exports in subfolders, eg `import thing from 'lodash/thing'",
154
+ },
155
+ ],
156
+ patterns: ['lodash.*'],
157
+ },
158
+ ],
159
+ },
160
+ },
161
+
162
+ // TypeScript-specific configuration
163
+ {
164
+ files: ['**/*.ts', '**/*.tsx', '**/*.mts'],
165
+ languageOptions: {
166
+ parser: tseslint.parser,
167
+ parserOptions: {
168
+ ...(tsconfigRootDir && { tsconfigRootDir }),
169
+ },
170
+ },
171
+ rules: {
172
+ // Enforce type imports
173
+ '@typescript-eslint/consistent-type-imports': [
174
+ 'error',
175
+ {
176
+ prefer: 'type-imports',
177
+ fixStyle: 'inline-type-imports',
178
+ },
179
+ ],
180
+ '@typescript-eslint/no-explicit-any': 'warn',
181
+ '@typescript-eslint/no-unused-vars': 'off',
182
+ '@typescript-eslint/explicit-function-return-type': 'off',
183
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
184
+ 'class-methods-use-this': 'off',
185
+ '@typescript-eslint/class-methods-use-this': [
186
+ 'error',
187
+ {
188
+ ignoreOverrideMethods: true,
189
+ ignoreClassesThatImplementAnInterface: true,
190
+ },
191
+ ],
192
+ '@typescript-eslint/no-empty-function': 'off',
193
+ 'no-unused-expressions': 'off',
194
+ '@typescript-eslint/no-unused-expressions': [
195
+ 'error',
196
+ {
197
+ allowShortCircuit: true,
198
+ allowTernary: true,
199
+ enforceForJSX: true,
200
+ },
201
+ ],
202
+ 'no-shadow': 'off',
203
+ '@typescript-eslint/no-shadow': [
204
+ 'error',
205
+ {
206
+ ignoreTypeValueShadow: true,
207
+ ignoreFunctionTypeParameterNameValueShadow: true,
208
+ },
209
+ ],
210
+ '@typescript-eslint/no-inferrable-types': 'error',
211
+ '@typescript-eslint/no-use-before-define': 'error',
212
+ '@typescript-eslint/no-require-imports': 'off',
213
+ },
214
+ },
215
+
216
+ // JavaScript files (allow require)
217
+ {
218
+ files: ['**/*.js', '**/*.cjs', '**/*.mjs'],
219
+ rules: {
220
+ '@typescript-eslint/no-require-imports': 'off',
221
+ },
222
+ },
223
+ ];
224
+ }
225
+
226
+ // Default export for direct use
227
+ export default createBaseConfig();
package/package.json CHANGED
@@ -1,19 +1,16 @@
1
1
  {
2
2
  "name": "@knapsack/eslint-config-starter",
3
3
  "description": "ESlint Config",
4
- "version": "5.0.0--canary.6593.4738696.0",
4
+ "version": "5.0.0",
5
5
  "bin": "./bin.js",
6
- "main": "eslint-config-base.js",
6
+ "main": "eslint.config.mjs",
7
7
  "exports": {
8
- ".": {
9
- "require": "./eslint-config-base.js"
10
- },
11
- "./ava": "./ava.json",
12
8
  "./creator": "./dist/eslint-config-starter-creator.js",
13
- "./esm": "./esm.json",
9
+ "./esm": "./configs/esm.mjs",
10
+ "./legacy": "./eslint-config-base.js",
14
11
  "./package": "./package.json",
15
12
  "./package.json": "./package.json",
16
- "./react": "./react.json"
13
+ "./react": "./configs/react.mjs"
17
14
  },
18
15
  "sideEffects": false,
19
16
  "scripts": {
@@ -24,30 +21,31 @@
24
21
  "start": "tsc --watch"
25
22
  },
26
23
  "dependencies": {
27
- "@knapsack/creator-utils": "5.0.0--canary.6593.4738696.0",
28
- "@knapsack/prettier-config": "5.0.0--canary.6593.4738696.0",
29
- "@rushstack/eslint-patch": "^1.8.0",
30
- "@typescript-eslint/eslint-plugin": "^7.18.0",
31
- "@typescript-eslint/parser": "^7.18.0",
32
- "eslint": "^8.57.0",
33
- "eslint-config-airbnb": "^19.0.4",
34
- "eslint-config-prettier": "^8.10.0",
24
+ "@eslint/compat": "^1.2.5",
25
+ "@eslint/eslintrc": "^3.2.0",
26
+ "@eslint/js": "^9.20.0",
27
+ "@knapsack/creator-utils": "5.0.0",
28
+ "@knapsack/prettier-config": "5.0.0",
29
+ "@typescript-eslint/eslint-plugin": "^8.24.0",
30
+ "@typescript-eslint/parser": "^8.24.0",
31
+ "eslint": "^9.20.0",
32
+ "eslint-config-prettier": "^10.0.1",
35
33
  "eslint-import-resolver-typescript": "^3.10.1",
36
- "eslint-plugin-ava": "^13.2.0",
37
- "eslint-plugin-import": "^2.29.1",
38
- "eslint-plugin-jsdoc": "^39.9.1",
39
- "eslint-plugin-jsx-a11y": "^6.8.0",
40
- "eslint-plugin-prettier": "^4.2.1",
41
- "eslint-plugin-promise": "^6.1.1",
42
- "eslint-plugin-react": "^7.34.1",
43
- "eslint-plugin-react-hooks": "^4.6.0",
44
- "eslint-plugin-unicorn": "^51.0.1",
45
- "eslint-plugin-unused-imports": "^3.2.0",
46
- "typescript": "^5.9.2",
47
- "typescript-eslint": "^7.18.0"
34
+ "eslint-plugin-import-x": "^4.6.1",
35
+ "eslint-plugin-jsdoc": "^50.6.3",
36
+ "eslint-plugin-jsx-a11y": "^6.10.2",
37
+ "eslint-plugin-prettier": "^5.2.3",
38
+ "eslint-plugin-promise": "^7.2.1",
39
+ "eslint-plugin-react": "^7.37.4",
40
+ "eslint-plugin-react-hooks": "^7.0.1",
41
+ "eslint-plugin-unicorn": "^57.0.0",
42
+ "eslint-plugin-unused-imports": "^4.1.4",
43
+ "globals": "^15.14.0",
44
+ "typescript": "^5.9.3",
45
+ "typescript-eslint": "^8.24.0"
48
46
  },
49
47
  "devDependencies": {
50
- "@types/node": "^20.19.22"
48
+ "@types/node": "^22.19.11"
51
49
  },
52
50
  "license": "GPL-2.0-or-later",
53
51
  "publishConfig": {
@@ -58,5 +56,5 @@
58
56
  "directory": "tools/eslint-config-starter",
59
57
  "type": "git"
60
58
  },
61
- "gitHead": "4738696cd5d75f977543e5484622c251b26db3a4"
59
+ "gitHead": "31e09ba72245b95bef52e73ce5076de51936286c"
62
60
  }
package/.eslintrc DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "extends": "./eslint-config-base.js"
3
- }
package/ava.json DELETED
@@ -1,31 +0,0 @@
1
- {
2
- "$schema": "https://json.schemastore.org/eslintrc",
3
- "plugins": ["ava"],
4
- "rules": {
5
- "ava/assertion-arguments": "off",
6
- "ava/hooks-order": "error",
7
- "ava/max-asserts": ["off", 5],
8
- "ava/no-async-fn-without-await": "error",
9
- "ava/no-cb-test": "off",
10
- "ava/no-duplicate-modifiers": "error",
11
- "ava/no-identical-title": "error",
12
- "ava/no-incorrect-deep-equal": "error",
13
- "ava/no-inline-assertions": "error",
14
- "ava/no-nested-tests": "error",
15
- "ava/no-only-test": "error",
16
- "ava/no-skip-assert": "error",
17
- "ava/no-skip-test": "off",
18
- "ava/no-todo-implementation": "error",
19
- "ava/no-todo-test": "warn",
20
- "ava/no-unknown-modifiers": "error",
21
- "ava/prefer-async-await": "error",
22
- "ava/prefer-power-assert": "off",
23
- "ava/prefer-t-regex": "error",
24
- "ava/test-title": "error",
25
- "ava/test-title-format": "off",
26
- "ava/use-t": "error",
27
- "ava/use-t-well": "error",
28
- "ava/use-test": "error",
29
- "ava/use-true-false": "error"
30
- }
31
- }
package/esm.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "$schema": "https://json.schemastore.org/eslintrc",
3
- "plugins": ["unicorn"],
4
- "rules": {
5
- "unicorn/prefer-module": "error",
6
- "unicorn/prefer-node-protocol": "error",
7
- "unicorn/prefer-top-level-await": "error"
8
- }
9
- }
package/react.json DELETED
@@ -1,47 +0,0 @@
1
- {
2
- "$schema": "https://json.schemastore.org/eslintrc",
3
- "plugins": ["react-hooks", "jsx-a11y"],
4
- "settings": {
5
- "react": {
6
- "version": "detect"
7
- }
8
- },
9
- "rules": {
10
- "jsx-a11y/anchor-is-valid": [
11
- "warn",
12
- {
13
- "aspects": ["invalidHref"]
14
- }
15
- ],
16
- "jsx-a11y/href-no-hash": "off",
17
- "react/boolean-prop-naming": [0],
18
- "react/destructuring-assignment": [0],
19
- "react/forbid-prop-types": [
20
- 2,
21
- {
22
- "forbid": ["any", "array"]
23
- }
24
- ],
25
- "react/no-unknown-property": [0],
26
- "react/prop-types": [0],
27
- "react/function-component-definition": [0],
28
- "react/no-unstable-nested-components": [
29
- "error",
30
- {
31
- "allowAsProps": true
32
- }
33
- ],
34
- "react/jsx-key": [2],
35
- "react-hooks/rules-of-hooks": "error",
36
- "react-hooks/exhaustive-deps": [2],
37
- "react/no-array-index-key": [2],
38
- "react/no-danger": [0],
39
- "react/jsx-props-no-spreading": [0],
40
- "react/sort-comp": [0],
41
- "react/static-property-placement": [0, "static public field"],
42
- "react/require-extension": [0],
43
- "react/jsx-filename-extension": [2, { "extensions": [".tsx", ".jsx"] }],
44
- "react/require-default-props": [0],
45
- "react/no-unused-prop-types": [0]
46
- }
47
- }