@vijayhardaha/dev-config 2.0.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  Reusable development configuration package for Next.js + TypeScript projects.
8
8
 
9
- > **v2.0.0** — Requires ESLint >=10. Native flat config only. No FlatCompat.
9
+ > **v2.0.4** — Requires ESLint >=10. Native flat config only. No FlatCompat.
10
10
 
11
11
  ## Features
12
12
 
@@ -21,17 +21,25 @@ Reusable development configuration package for Next.js + TypeScript projects.
21
21
  ## Installation
22
22
 
23
23
  ```bash
24
- bun install @vijayhardaha/dev-config --dev
24
+ bun add --dev @vijayhardaha/dev-config
25
25
  ```
26
26
 
27
27
  ### Install Required Packages
28
28
 
29
29
  ```bash
30
- bun add --dev eslint @eslint/compat prettier @prettier/plugin-xml eslint-plugin-prettier globals eslint-plugin-jsdoc eslint-plugin-import-x typescript typescript-eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser
30
+ bun add --dev eslint @eslint/compat eslint-config-prettier prettier @prettier/plugin-xml eslint-plugin-prettier globals eslint-plugin-jsdoc eslint-plugin-import-x @typescript-eslint/eslint-plugin @typescript-eslint/parser typescript typescript-eslint husky
31
31
  ```
32
32
 
33
33
  ### Install Optional Packages
34
34
 
35
+ Only install what you need based on your project setup.
36
+
37
+ #### TypeScript Import Resolution
38
+
39
+ ```bash
40
+ bun add --dev eslint-import-resolver-typescript
41
+ ```
42
+
35
43
  #### Stylelint
36
44
 
37
45
  ```bash
@@ -53,7 +61,7 @@ bun add --dev @next/eslint-plugin-next eslint-config-next
53
61
  #### Commitlint
54
62
 
55
63
  ```bash
56
- bun add --dev husky @commitlint/cli @commitlint/config-conventional @commitlint/types
64
+ bun add --dev @commitlint/cli @commitlint/config-conventional @commitlint/types
57
65
  ```
58
66
 
59
67
  #### Next Sitemap
@@ -79,7 +87,14 @@ v2 drops FlatCompat and uses native ESLint 10 flat configs throughout.
79
87
 
80
88
  1. Install ESLint 10+: `bun add --dev eslint@10`
81
89
  2. Replace `eslint-plugin-import` with `eslint-plugin-import-x`
82
- 3. Remove unused deps: `@eslint/eslintrc`, `@eslint/js`, `eslint-config-prettier`, `eslint-import-resolver-typescript`
90
+ 3. Remove unused deps: `@eslint/eslintrc`, `@eslint/js`
91
+
92
+ ### What's new in v2.0.4
93
+
94
+ - **`eslint-config-prettier` restored** — added back to peer deps (required by `eslint-plugin-prettier/recommended`)
95
+ - **`eslint-import-resolver-typescript` restored** — added back as optional peer for TypeScript import resolution
96
+ - **All packages declared as peer deps** — every config module's dependencies are declared with proper `peerDependenciesMeta`
97
+ - **Flat config resolver fix** — switched from string-based `import-x/resolver` to `import-x/resolver-next` with `createTypeScriptImportResolver` for ESLint 10 compatibility
83
98
 
84
99
  ## Quick Start
85
100
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vijayhardaha/dev-config",
3
- "version": "2.0.3",
3
+ "version": "2.1.0",
4
4
  "description": "Reusable development configurations for Next.js + TypeScript projects",
5
5
  "scripts": {
6
6
  "lint": "eslint .",
@@ -68,32 +68,55 @@
68
68
  "@commitlint/cli": "^21.0.2",
69
69
  "@commitlint/config-conventional": "^21.0.2",
70
70
  "@commitlint/types": "^21.0.1",
71
- "@vitest/coverage-v8": "^4.1.7",
72
- "eslint-config-next": "^16.2.6",
71
+ "@typescript-eslint/parser": "^8.60.1",
72
+ "@typescript-eslint/eslint-plugin": "^8.60.1",
73
+ "@vitest/coverage-v8": "^4.1.8",
74
+ "eslint": "^10.4.1",
75
+ "eslint-config-next": "^16.2.7",
76
+ "eslint-config-prettier": "^10.1.8",
77
+ "eslint-plugin-import-x": "^4.16.2",
78
+ "eslint-plugin-jsdoc": "^63.0.1",
73
79
  "eslint-plugin-jsx-a11y": "^6.10.2",
80
+ "eslint-plugin-prettier": "^5.5.6",
74
81
  "eslint-plugin-react": "^7.37.5",
75
82
  "eslint-plugin-react-hooks": "^7.1.1",
76
- "next-sitemap": "^4.2.3",
77
- "release-it": "^20.0.1",
78
- "stylelint": "^17.12.0",
79
- "stylelint-config-property-sort-order-smacss": "^11.2.0",
80
- "stylelint-config-standard-scss": "^17.0.0",
81
- "stylelint-order": "^8.1.1",
82
- "vitest": "^4.1.7"
83
+ "globals": "^17.6.0",
84
+ "husky": "^9.1.7",
85
+ "prettier": "^3.8.3",
86
+ "@prettier/plugin-xml": "^3.4.2",
87
+ "release-it": "^20.2.0",
88
+ "typescript": "^6.0.3",
89
+ "typescript-eslint": "^8.60.1",
90
+ "vitest": "^4.1.8"
83
91
  },
84
92
  "peerDependencies": {
93
+ "@commitlint/cli": ">=21",
94
+ "@commitlint/config-conventional": ">=21",
95
+ "@commitlint/types": ">=21",
85
96
  "@eslint/compat": ">=2",
97
+ "@next/eslint-plugin-next": ">=16",
86
98
  "@prettier/plugin-xml": ">=3",
87
99
  "@typescript-eslint/eslint-plugin": ">=8",
88
100
  "@typescript-eslint/parser": ">=8",
89
101
  "eslint": ">=10",
102
+ "eslint-config-next": ">=16",
103
+ "eslint-config-prettier": ">=10",
104
+ "eslint-import-resolver-typescript": ">=4",
90
105
  "eslint-plugin-import-x": ">=4",
91
106
  "eslint-plugin-jsdoc": ">=62",
107
+ "eslint-plugin-jsx-a11y": ">=6",
92
108
  "eslint-plugin-prettier": ">=5",
109
+ "eslint-plugin-react": ">=7",
110
+ "eslint-plugin-react-hooks": ">=5",
93
111
  "globals": ">=17",
94
112
  "husky": ">=9",
95
- "prettier": "^3.8.3",
96
- "typescript": ">=6",
113
+ "next-sitemap": ">=4",
114
+ "prettier": ">=3",
115
+ "stylelint": ">=17",
116
+ "stylelint-config-property-sort-order-smacss": ">=11",
117
+ "stylelint-config-standard-scss": ">=17",
118
+ "stylelint-order": ">=8",
119
+ "typescript": ">=5",
97
120
  "typescript-eslint": ">=8"
98
121
  },
99
122
  "peerDependenciesMeta": {
@@ -109,9 +132,18 @@
109
132
  "@next/eslint-plugin-next": {
110
133
  "optional": true
111
134
  },
135
+ "@typescript-eslint/eslint-plugin": {
136
+ "optional": true
137
+ },
138
+ "@typescript-eslint/parser": {
139
+ "optional": true
140
+ },
112
141
  "eslint-config-next": {
113
142
  "optional": true
114
143
  },
144
+ "eslint-import-resolver-typescript": {
145
+ "optional": true
146
+ },
115
147
  "eslint-plugin-jsx-a11y": {
116
148
  "optional": true
117
149
  },
@@ -121,6 +153,9 @@
121
153
  "eslint-plugin-react-hooks": {
122
154
  "optional": true
123
155
  },
156
+ "husky": {
157
+ "optional": true
158
+ },
124
159
  "next-sitemap": {
125
160
  "optional": true
126
161
  },
@@ -135,12 +170,19 @@
135
170
  },
136
171
  "stylelint-order": {
137
172
  "optional": true
173
+ },
174
+ "typescript": {
175
+ "optional": true
176
+ },
177
+ "typescript-eslint": {
178
+ "optional": true
138
179
  }
139
180
  },
140
181
  "overrides": {
141
182
  "undici": "^7.0.0"
142
183
  },
143
184
  "trustedDependencies": [
185
+ "sharp",
144
186
  "unrs-resolver"
145
187
  ]
146
188
  }
@@ -1,6 +1,9 @@
1
+ import { existsSync } from 'node:fs';
2
+ import path from 'node:path';
3
+
1
4
  import { fixupPluginRules } from '@eslint/compat';
2
- import { defineConfig } from 'eslint/config';
3
- import importX from 'eslint-plugin-import-x';
5
+ import { defineConfig, includeIgnoreFile } from 'eslint/config';
6
+ import { createNodeResolver, flatConfigs as importXFlatConfigs } from 'eslint-plugin-import-x';
4
7
  import jsdocPlugin from 'eslint-plugin-jsdoc';
5
8
  import prettierRecommended from 'eslint-plugin-prettier/recommended';
6
9
 
@@ -9,6 +12,13 @@ import { commonLanguageOptions } from './language-options.js';
9
12
  import { commonRules } from './rules.js';
10
13
  import { commonParser } from './setup.js';
11
14
 
15
+ let createTypeScriptImportResolver;
16
+ try {
17
+ createTypeScriptImportResolver = (await import('eslint-import-resolver-typescript')).createTypeScriptImportResolver;
18
+ } catch {
19
+ createTypeScriptImportResolver = null;
20
+ }
21
+
12
22
  /**
13
23
  * Filters conditional plugins based on user options.
14
24
  *
@@ -166,7 +176,12 @@ const buildConfigObject = ({
166
176
  ...(typescript && { parserOptions: { tsconfigRootDir: process.cwd(), ...parserOptions } }),
167
177
  },
168
178
  settings: {
169
- ...(opts.importOrder && { 'import-x/resolver': { typescript: {} } }),
179
+ ...(opts.importOrder && {
180
+ 'import-x/resolver-next': [
181
+ createNodeResolver(),
182
+ ...(createTypeScriptImportResolver ? [createTypeScriptImportResolver()] : []),
183
+ ],
184
+ }),
170
185
  ...(opts.jsdoc && { jsdoc: { mode: 'typescript' } }),
171
186
  ...extraSettings,
172
187
  ...settings,
@@ -215,7 +230,7 @@ export const buildConfig = ({
215
230
 
216
231
  const mergedPlugins = [
217
232
  ...builtinPlugins,
218
- opts.importOrder && importX.flatConfigs.recommended,
233
+ opts.importOrder && importXFlatConfigs.recommended,
219
234
  opts.jsdoc && jsdocPlugin.configs['flat/recommended'],
220
235
  opts.prettier && prettierRecommended,
221
236
  ...conditionalPluginList,
@@ -228,6 +243,9 @@ export const buildConfig = ({
228
243
  const parsedConfigs = typescript ? stripParser(strippedConfigs) : strippedConfigs;
229
244
  const mergedGlobalIgnores = mergeGlobalIgnores(opts.globalIgnores);
230
245
 
246
+ const gitignorePath = path.resolve(process.cwd(), '.gitignore');
247
+ const gitignoreConfig = existsSync(gitignorePath) ? includeIgnoreFile(gitignorePath) : null;
248
+
231
249
  const configObject = buildConfigObject({
232
250
  filePatterns,
233
251
  opts,
@@ -239,5 +257,10 @@ export const buildConfig = ({
239
257
  extraRules,
240
258
  });
241
259
 
242
- return defineConfig([...mergedGlobalIgnores, ...parsedConfigs, configObject]);
260
+ return defineConfig([
261
+ ...mergedGlobalIgnores,
262
+ ...(gitignoreConfig ? [gitignoreConfig] : []),
263
+ ...parsedConfigs,
264
+ configObject,
265
+ ]);
243
266
  };
@@ -49,4 +49,44 @@ describe('eslint/lib/build-config.js', () => {
49
49
  expect(configNames).toContain('test-flat-config');
50
50
  expect(configNames).toContain('test-flat-object');
51
51
  });
52
+
53
+ // Test that buildConfig sets import-x/resolver-next when importOrder is enabled.
54
+ it('should configure import-x/resolver-next with node resolver when importOrder is enabled', async () => {
55
+ const module = await import('./build-config.js');
56
+ const { files } = await import('./files.js');
57
+
58
+ const result = module.buildConfig({ files: files.withoutTs, options: { importOrder: true } });
59
+
60
+ // The last config object in the array should have the resolver settings
61
+ const configObject = result[result.length - 1];
62
+ expect(configObject.settings).toBeDefined();
63
+ expect(configObject.settings['import-x/resolver-next']).toBeDefined();
64
+ expect(Array.isArray(configObject.settings['import-x/resolver-next'])).toBe(true);
65
+ // Should at least have the node resolver
66
+ expect(configObject.settings['import-x/resolver-next'].length).toBeGreaterThanOrEqual(1);
67
+ });
68
+
69
+ // Test that buildConfig omits import-x/resolver-next when importOrder is disabled.
70
+ it('should omit import-x/resolver-next when importOrder is disabled', async () => {
71
+ const module = await import('./build-config.js');
72
+ const { files } = await import('./files.js');
73
+
74
+ const result = module.buildConfig({ files: files.withoutTs, options: { importOrder: false } });
75
+
76
+ const configObject = result[result.length - 1];
77
+ expect(configObject.settings).toBeDefined();
78
+ expect(configObject.settings['import-x/resolver-next']).toBeUndefined();
79
+ });
80
+
81
+ // Test that buildConfig includes .gitignore patterns via includeIgnoreFile.
82
+ it('should include .gitignore patterns from project root', async () => {
83
+ const module = await import('./build-config.js');
84
+ const { files } = await import('./files.js');
85
+
86
+ const result = module.buildConfig({ files: files.withoutTs, options: {} });
87
+
88
+ // When .gitignore exists at the project root, includeIgnoreFile adds a config with ignores.
89
+ const hasIgnoreConfig = result.some((config) => config.ignores && config.ignores.length > 0);
90
+ expect(hasIgnoreConfig).toBe(true);
91
+ });
52
92
  });
@@ -1,4 +1,4 @@
1
1
  {
2
- "compilerOptions": { "jsx": "react-jsx", "resolveJsonModule": true, "baseUrl": ".", "paths": { "@/*": ["./src/*"] } },
2
+ "compilerOptions": { "jsx": "react-jsx", "resolveJsonModule": true, "paths": { "@/*": ["./src/*"] } },
3
3
  "exclude": ["node_modules", ".next", "out"]
4
4
  }