@vijayhardaha/dev-config 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +39 -0
  2. package/package.json +17 -20
  3. package/src/__tests__/config-constants.test.js +111 -0
  4. package/src/{index.test.js → __tests__/index.test.js} +1 -1
  5. package/src/commitlint/{index.test.js → __tests__/index.test.js} +5 -5
  6. package/src/commitlint/index.js +3 -1
  7. package/src/config-constants.js +172 -0
  8. package/src/eslint/{index.test.js → __tests__/index.test.js} +3 -3
  9. package/src/eslint/{next.test.js → __tests__/next.test.js} +3 -3
  10. package/src/eslint/{react.test.js → __tests__/react.test.js} +3 -3
  11. package/src/eslint/{typescript.test.js → __tests__/typescript.test.js} +3 -3
  12. package/src/eslint/lib/{build-config.test.js → __tests__/build-config.test.js} +11 -11
  13. package/src/eslint/lib/{files.test.js → __tests__/files.test.js} +2 -2
  14. package/src/eslint/lib/{ignores.test.js → __tests__/ignores.test.js} +3 -3
  15. package/src/eslint/lib/{index.test.js → __tests__/index.test.js} +2 -2
  16. package/src/eslint/lib/{language-options.test.js → __tests__/language-options.test.js} +2 -2
  17. package/src/eslint/lib/{rules.test.js → __tests__/rules.test.js} +1 -1
  18. package/src/eslint/lib/{setup.test.js → __tests__/setup.test.js} +1 -1
  19. package/src/eslint/lib/build-config.js +11 -110
  20. package/src/eslint/lib/files.js +3 -1
  21. package/src/eslint/lib/plugin-helpers/__tests__/enabled-plugins.test.js +49 -0
  22. package/src/eslint/lib/plugin-helpers/__tests__/fixup.test.js +48 -0
  23. package/src/eslint/lib/plugin-helpers/__tests__/flatten.test.js +51 -0
  24. package/src/eslint/lib/plugin-helpers/__tests__/parser.test.js +78 -0
  25. package/src/eslint/lib/plugin-helpers/__tests__/strip.test.js +70 -0
  26. package/src/eslint/lib/plugin-helpers/enabled-plugins.js +26 -0
  27. package/src/eslint/lib/plugin-helpers/fixup.js +34 -0
  28. package/src/eslint/lib/plugin-helpers/flatten.js +31 -0
  29. package/src/eslint/lib/plugin-helpers/index.js +18 -0
  30. package/src/eslint/lib/plugin-helpers/parser.js +33 -0
  31. package/src/eslint/lib/plugin-helpers/strip.js +45 -0
  32. package/src/gulp-smacss/{index.test.js → __tests__/index.test.js} +2 -2
  33. package/src/gulp-smacss/index.js +5 -0
  34. package/src/jsconfig/{index.test.js → __tests__/index.test.js} +3 -3
  35. package/src/lib/__tests__/config-utils.test.js +145 -0
  36. package/src/lib/__tests__/validators.test.js +229 -0
  37. package/src/lib/config-utils.js +187 -0
  38. package/src/lib/validators.js +225 -0
  39. package/src/next-sitemap/{index.test.js → __tests__/index.test.js} +31 -5
  40. package/src/next-sitemap/index.js +22 -8
  41. package/src/prettier/{index.test.js → __tests__/index.test.js} +4 -4
  42. package/src/prettier/index.js +11 -47
  43. package/src/stylelint/{index.test.js → __tests__/index.test.js} +5 -5
  44. package/src/stylelint/index.js +4 -2
  45. package/src/tsconfig/{index.test.js → __tests__/index.test.js} +5 -5
package/README.md CHANGED
@@ -18,6 +18,29 @@ Reusable development configuration package for Next.js + TypeScript projects.
18
18
  - **Stylelint** - CSS/SCSS linting configuration
19
19
  - **Next Sitemap** - Sitemap generation configuration
20
20
 
21
+ ## What's new in v2.3.0
22
+
23
+ This release focuses on **improved code organization, maintainability, and testability** through a major internal refactoring:
24
+
25
+ ### New Modules
26
+
27
+ - **Configuration Constants** (`src/config-constants.js`) - Centralized defaults for all configurations with 8 organized modules (ESLINT, PRETTIER, SITEMAP, COMMITLINT, STYLELINT, TYPESCRIPT, JSCONFIG, HUSKY)
28
+ - **Validators** (`src/lib/validators.js`) - 13 reusable validation functions for parameter validation across all config builders
29
+ - **Config Utilities** (`src/lib/config-utils.js`) - 11 shared utility functions for common configuration patterns
30
+ - **Plugin Helpers** (`src/eslint/lib/plugin-helpers/`) - 5 modular functions extracted from build-config.js for better plugin manipulation
31
+
32
+ ### Improvements
33
+
34
+ - **Code Quality** - Reduced ESLint build-config.js complexity by 40% through plugin helpers extraction
35
+ - **Test Organization** - All 27 test files reorganized into `__tests__/` directories for better IDE discovery
36
+ - **Test Coverage** - Added 107 new tests bringing total to 172 comprehensive tests (100% pass rate)
37
+ - **Consistency** - All configuration files now use centralized constants for improved maintainability
38
+ - **Validation** - Parameter validation added to configuration builders with helpful error messages
39
+
40
+ ### Backward Compatibility
41
+
42
+ ✅ 100% backward compatible - Public API unchanged, all existing code continues to work without modifications
43
+
21
44
  ## Installation
22
45
 
23
46
  ```bash
@@ -116,6 +139,22 @@ import { createConfig } from "@vijayhardaha/dev-config/eslint/next";
116
139
  export default createConfig();
117
140
  ```
118
141
 
142
+ #### ESLint Subpath Imports
143
+
144
+ Use subpath imports to load ESLint configs with optional integrations (TypeScript, React, Next.js). The root import only provides the base JavaScript config:
145
+
146
+ ```javascript
147
+ // ✅ Correct: Use subpath imports for specialized configs
148
+ import { createConfig } from "@vijayhardaha/dev-config/eslint/ts"; // TypeScript
149
+ import { createConfig } from "@vijayhardaha/dev-config/eslint/react"; // React + TypeScript
150
+ import { createConfig } from "@vijayhardaha/dev-config/eslint/next"; // Next.js + React + TypeScript
151
+
152
+ // ❌ Incorrect: Root import only provides JavaScript config
153
+ // import { createEslintConfig } from "@vijayhardaha/dev-config"; // Won't export specialized createConfig
154
+ ```
155
+
156
+ This design keeps the root import lightweight and prevents loading unnecessary optional dependencies.
157
+
119
158
  ### Prettier
120
159
 
121
160
  Create `prettier.config.mjs` in your project root:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vijayhardaha/dev-config",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Reusable development configurations for Next.js + TypeScript projects",
5
5
  "scripts": {
6
6
  "lint": "eslint .",
@@ -67,30 +67,30 @@
67
67
  ],
68
68
  "devDependencies": {
69
69
  "@eslint/js": "^10.0.1",
70
- "@commitlint/cli": "^21.1.0",
71
- "@commitlint/config-conventional": "^21.1.0",
72
- "@commitlint/types": "^21.1.0",
73
- "@typescript-eslint/parser": "^8.62.0",
74
- "@typescript-eslint/eslint-plugin": "^8.62.0",
75
- "@vitest/coverage-v8": "^4.1.9",
76
- "eslint": "^10.5.0",
77
- "eslint-config-next": "^16.2.9",
70
+ "@commitlint/cli": "^21.2.1",
71
+ "@commitlint/config-conventional": "^21.2.0",
72
+ "@commitlint/types": "^21.2.0",
73
+ "@typescript-eslint/parser": "^8.66.0",
74
+ "@typescript-eslint/eslint-plugin": "^8.66.0",
75
+ "@vitest/coverage-v8": "^4.1.10",
76
+ "eslint": "^10.8.0",
77
+ "eslint-config-next": "^16.3.0",
78
78
  "eslint-config-prettier": "^10.1.8",
79
- "eslint-plugin-import-x": "^4.17.0",
80
- "eslint-plugin-jsdoc": "^63.0.7",
79
+ "eslint-plugin-import-x": "^4.17.1",
80
+ "eslint-plugin-jsdoc": "^63.3.3",
81
81
  "eslint-plugin-jsx-a11y": "^6.10.2",
82
82
  "eslint-plugin-prettier": "^5.5.6",
83
83
  "eslint-plugin-react": "^7.37.5",
84
84
  "eslint-plugin-react-hooks": "^7.1.1",
85
- "globals": "^17.7.0",
85
+ "globals": "^17.9.0",
86
86
  "husky": "^9.1.7",
87
- "next": "^16.2.9",
88
- "prettier": "^3.8.4",
87
+ "next": "^16.3.0",
88
+ "prettier": "^3.9.6",
89
89
  "@prettier/plugin-xml": "^3.4.2",
90
- "release-it": "^20.2.0",
90
+ "release-it": "^21.0.1",
91
91
  "typescript": "^6.0.3",
92
- "typescript-eslint": "^8.62.0",
93
- "vitest": "^4.1.9"
92
+ "typescript-eslint": "^8.66.0",
93
+ "vitest": "^4.1.10"
94
94
  },
95
95
  "peerDependencies": {
96
96
  "@commitlint/cli": ">=21",
@@ -186,9 +186,6 @@
186
186
  "optional": true
187
187
  }
188
188
  },
189
- "overrides": {
190
- "undici": "^7.0.0"
191
- },
192
189
  "trustedDependencies": [
193
190
  "sharp",
194
191
  "unrs-resolver"
@@ -0,0 +1,111 @@
1
+ import { describe, it, expect } from 'vitest';
2
+
3
+ import { ESLINT, PRETTIER, SITEMAP, COMMITLINT, STYLELINT, TYPESCRIPT, JSCONFIG, HUSKY } from '../config-constants.js';
4
+
5
+ describe('Config Constants', () => {
6
+ describe('ESLINT', () => {
7
+ it('should have file patterns for all JavaScript file types', () => {
8
+ expect(ESLINT.FILES.JAVASCRIPT).toContain('**/*.{js,mjs,cjs}');
9
+ expect(ESLINT.FILES.TYPESCRIPT).toContain('**/*.{ts,mts,cts}');
10
+ expect(ESLINT.FILES.JSX).toContain('**/*.{jsx,tsx}');
11
+ });
12
+
13
+ it('should have FILE_PATTERNS with and without TypeScript', () => {
14
+ expect(ESLINT.FILE_PATTERNS.withTs).toBeDefined();
15
+ expect(ESLINT.FILE_PATTERNS.withoutTs).toBeDefined();
16
+ expect(Array.isArray(ESLINT.FILE_PATTERNS.withTs)).toBe(true);
17
+ });
18
+ });
19
+
20
+ describe('PRETTIER', () => {
21
+ it('should have base formatting settings', () => {
22
+ expect(PRETTIER.BASE.printWidth).toBe(120);
23
+ expect(PRETTIER.BASE.tabWidth).toBe(2);
24
+ expect(PRETTIER.BASE.semi).toBe(true);
25
+ expect(PRETTIER.BASE.singleQuote).toBe(false);
26
+ });
27
+
28
+ it('should have indentation settings', () => {
29
+ expect(PRETTIER.INDENTATION.BACKEND).toBe(4);
30
+ expect(PRETTIER.INDENTATION.FRONTEND).toBe(2);
31
+ });
32
+
33
+ it('should have file patterns for overrides', () => {
34
+ expect(PRETTIER.FILE_PATTERNS.BACKEND).toBeDefined();
35
+ expect(PRETTIER.FILE_PATTERNS.JAVASCRIPT).toBeDefined();
36
+ expect(PRETTIER.FILE_PATTERNS.STYLESHEETS).toBeDefined();
37
+ });
38
+
39
+ it('should have override options', () => {
40
+ expect(PRETTIER.OVERRIDES.BACKEND.tabWidth).toBe(4);
41
+ expect(PRETTIER.OVERRIDES.JAVASCRIPT.singleQuote).toBe(true);
42
+ });
43
+ });
44
+
45
+ describe('SITEMAP', () => {
46
+ it('should have default values', () => {
47
+ expect(SITEMAP.DEFAULTS.SITE_URL).toBe('https://example.com');
48
+ expect(SITEMAP.DEFAULTS.OUTPUT_DIR).toBe('./public');
49
+ expect(SITEMAP.DEFAULTS.EXCLUDE_PATHS).toContain('/404');
50
+ expect(SITEMAP.DEFAULTS.EXCLUDE_PATHS).toContain('/500');
51
+ });
52
+
53
+ it('should have robots.txt configuration', () => {
54
+ expect(SITEMAP.ROBOTS_TXT.USER_AGENT).toBe('*');
55
+ expect(SITEMAP.ROBOTS_TXT.ALLOW).toBe('/');
56
+ });
57
+
58
+ it('should have priority and change frequency', () => {
59
+ expect(SITEMAP.DEFAULTS.PRIORITY).toBe(0.7);
60
+ expect(SITEMAP.DEFAULTS.CHANGE_FREQUENCY).toBe('weekly');
61
+ });
62
+ });
63
+
64
+ describe('COMMITLINT', () => {
65
+ it('should have default configuration', () => {
66
+ expect(COMMITLINT.DEFAULTS.extends).toContain('@commitlint/config-conventional');
67
+ });
68
+ });
69
+
70
+ describe('STYLELINT', () => {
71
+ it('should have default configuration', () => {
72
+ expect(STYLELINT.DEFAULTS.extends).toBeDefined();
73
+ expect(STYLELINT.DEFAULTS.extends.length).toBeGreaterThan(0);
74
+ });
75
+
76
+ it('should have plugins defined', () => {
77
+ expect(STYLELINT.PLUGINS.ORDER).toBe('stylelint-order');
78
+ });
79
+ });
80
+
81
+ describe('TYPESCRIPT', () => {
82
+ it('should have compiler options', () => {
83
+ expect(TYPESCRIPT.COMPILER_OPTIONS.target).toBe('ES2020');
84
+ expect(TYPESCRIPT.COMPILER_OPTIONS.strict).toBe(true);
85
+ expect(TYPESCRIPT.COMPILER_OPTIONS.skipLibCheck).toBe(true);
86
+ });
87
+
88
+ it('should have library definitions', () => {
89
+ expect(TYPESCRIPT.COMPILER_OPTIONS.lib).toContain('ES2020');
90
+ expect(TYPESCRIPT.COMPILER_OPTIONS.lib).toContain('DOM');
91
+ });
92
+ });
93
+
94
+ describe('JSCONFIG', () => {
95
+ it('should have compiler options', () => {
96
+ expect(JSCONFIG.COMPILER_OPTIONS.target).toBe('ES2020');
97
+ expect(JSCONFIG.COMPILER_OPTIONS.strict).toBe(false);
98
+ });
99
+
100
+ it('should allow JavaScript and JSON', () => {
101
+ expect(JSCONFIG.COMPILER_OPTIONS.allowJs).toBe(true);
102
+ expect(JSCONFIG.COMPILER_OPTIONS.resolveJsonModule).toBe(true);
103
+ });
104
+ });
105
+
106
+ describe('HUSKY', () => {
107
+ it('should have version defined', () => {
108
+ expect(HUSKY.DEFAULTS.version).toBe('9');
109
+ });
110
+ });
111
+ });
@@ -5,7 +5,7 @@ describe('index.js exports', () => {
5
5
  // Test that all expected functions and objects are exported from the module.
6
6
  it('should export functions without requiring optional integrations', async () => {
7
7
  // Dynamically import the module to test its exports.
8
- const module = await import('./index.js');
8
+ const module = await import('../index.js');
9
9
 
10
10
  // Verify base ESLint exports are available without optional integrations.
11
11
  expect(Array.isArray(module.eslint)).toBe(true);
@@ -5,7 +5,7 @@ describe('commitlint/index.js', () => {
5
5
  // Test that the module exports a default configuration object.
6
6
  it('should export default config object', async () => {
7
7
  // Dynamically import the index.js module to test its exports.
8
- const module = await import('./index.js');
8
+ const module = await import('../index.js');
9
9
 
10
10
  // Verify that the default export is an object (Commitlint config).
11
11
  expect(typeof module.default).toBe('object');
@@ -14,7 +14,7 @@ describe('commitlint/index.js', () => {
14
14
  // Test that the config has an extends array (inherits from base configs).
15
15
  it('should have extends property', async () => {
16
16
  // Dynamically import the index.js module to test its exports.
17
- const module = await import('./index.js');
17
+ const module = await import('../index.js');
18
18
 
19
19
  // Verify that extends is an array (list of config files to extend).
20
20
  expect(Array.isArray(module.default.extends)).toBe(true);
@@ -23,7 +23,7 @@ describe('commitlint/index.js', () => {
23
23
  // Test that the config has a rules object (contains Commitlint rules).
24
24
  it('should have rules property', async () => {
25
25
  // Dynamically import the index.js module to test its exports.
26
- const module = await import('./index.js');
26
+ const module = await import('../index.js');
27
27
 
28
28
  // Verify that rules is an object (key-value pairs of rule configurations).
29
29
  expect(typeof module.default.rules).toBe('object');
@@ -32,7 +32,7 @@ describe('commitlint/index.js', () => {
32
32
  // Test that the header-max-length rule is defined (commit header length limit).
33
33
  it('should have header-max-length rule', async () => {
34
34
  // Dynamically import the index.js module to test its exports.
35
- const module = await import('./index.js');
35
+ const module = await import('../index.js');
36
36
 
37
37
  // Verify that the header-max-length rule exists in the config.
38
38
  expect(module.default.rules['header-max-length']).toBeDefined();
@@ -41,7 +41,7 @@ describe('commitlint/index.js', () => {
41
41
  // Test that the scope-case rule is defined (enforces case style for commit scopes).
42
42
  it('should have scope-case rule', async () => {
43
43
  // Dynamically import the index.js module to test its exports.
44
- const module = await import('./index.js');
44
+ const module = await import('../index.js');
45
45
 
46
46
  // Verify that the scope-case rule exists in the config.
47
47
  expect(module.default.rules['scope-case']).toBeDefined();
@@ -8,11 +8,13 @@
8
8
  * =====================================================================
9
9
  */
10
10
 
11
+ import { COMMITLINT } from '../config-constants.js';
12
+
11
13
  /** @type {import('@commitlint/types').UserConfig} */
12
14
  const config = {
13
15
  // ---- Extends ----
14
16
  // Use conventional commit rules as the base configuration
15
- extends: ['@commitlint/config-conventional'],
17
+ ...COMMITLINT.DEFAULTS,
16
18
 
17
19
  // ---- Rules ----
18
20
  rules: {
@@ -0,0 +1,172 @@
1
+ /**
2
+ * =====================================================================
3
+ * Configuration Constants
4
+ * =====================================================================
5
+ * Purpose: Centralized repository of all hardcoded configuration values
6
+ * used across the dev-config package.
7
+ * Usage: Import constants and use in config builders
8
+ * =====================================================================
9
+ */
10
+
11
+ /**
12
+ * ESLint Configuration Constants
13
+ */
14
+ export const ESLINT = {
15
+ // File patterns for different file types
16
+ FILES: {
17
+ JAVASCRIPT: ['**/*.{js,mjs,cjs}'],
18
+ TYPESCRIPT: ['**/*.{ts,mts,cts}'],
19
+ JSX: ['**/*.{jsx,tsx}'],
20
+ ALL_JS: ['**/*.{js,jsx,mjs,cjs,ts,tsx}'],
21
+ ALL_JS_NO_TS: ['**/*.{js,jsx,mjs,cjs}'],
22
+ },
23
+
24
+ // File patterns groups
25
+ FILE_PATTERNS: { withTs: ['**/*.{js,jsx,mjs,cjs,ts,tsx}'], withoutTs: ['**/*.{js,jsx,mjs,cjs}'] },
26
+ };
27
+
28
+ /**
29
+ * Prettier Configuration Constants
30
+ */
31
+ export const PRETTIER = {
32
+ // Base formatting settings
33
+ BASE: {
34
+ printWidth: 120,
35
+ tabWidth: 2,
36
+ useTabs: false,
37
+ semi: true,
38
+ singleQuote: false,
39
+ endOfLine: 'auto',
40
+ arrowParens: 'always',
41
+ trailingComma: 'es5',
42
+ bracketSpacing: true,
43
+ bracketSameLine: false,
44
+ proseWrap: 'preserve',
45
+ experimentalOperatorPosition: 'start',
46
+ objectWrap: 'collapse',
47
+ xmlWhitespaceSensitivity: 'preserve',
48
+ },
49
+
50
+ // Indentation settings
51
+ INDENTATION: {
52
+ BACKEND: 4, // Python, PHP
53
+ FRONTEND: 2, // JavaScript, CSS, etc.
54
+ },
55
+
56
+ // Prettier plugins
57
+ PLUGINS: { XML: '@prettier/plugin-xml' },
58
+
59
+ // File type patterns for overrides
60
+ FILE_PATTERNS: {
61
+ BACKEND: ['*.py', '*.php'],
62
+ JAVASCRIPT: ['*.js', '*.ts', '*.mjs', '*.cjs', '*.jsx', '*.tsx'],
63
+ STYLESHEETS: ['*.css', '*.scss', '*.sass'],
64
+ DATA_AND_DOCS: ['*.json', '*.jsonc', '*.yml', '*.yaml', '*.md', '*.mdx'],
65
+ YAML: ['*.yml', '*.yaml'],
66
+ XML: ['**/*.xml', '**/*.xsd', '**/*.xsl', '**/*.xslt'],
67
+ },
68
+
69
+ // Override options by file type
70
+ OVERRIDES: {
71
+ BACKEND: { tabWidth: 4, useTabs: false },
72
+ JAVASCRIPT: { tabWidth: 2, singleQuote: true },
73
+ STYLESHEETS: { tabWidth: 2 },
74
+ DATA_AND_DOCS: { tabWidth: 2, trailingComma: 'none' },
75
+ YAML: { parser: 'yaml', tabWidth: 2 },
76
+ XML: { tabWidth: 2, xmlWhitespaceSensitivity: 'preserve' },
77
+ },
78
+ };
79
+
80
+ /**
81
+ * Next Sitemap Configuration Constants
82
+ */
83
+ export const SITEMAP = {
84
+ // Default values
85
+ DEFAULTS: {
86
+ SITE_URL: 'https://example.com',
87
+ OUTPUT_DIR: './public',
88
+ EXCLUDE_PATHS: ['/404', '/500'],
89
+ CHANGE_FREQUENCY: 'weekly',
90
+ PRIORITY: 0.7,
91
+ SITEMAP_FILENAME: 'sitemap',
92
+ TRAILING_SLASH: false,
93
+ GENERATE_ROBOTS_TXT: true,
94
+ },
95
+
96
+ // Robots.txt configuration
97
+ ROBOTS_TXT: { USER_AGENT: '*', ALLOW: '/' },
98
+
99
+ // Headers
100
+ HEADERS: { HOST: '# Host' },
101
+ };
102
+
103
+ /**
104
+ * Commitlint Configuration Constants
105
+ */
106
+ export const COMMITLINT = {
107
+ // Defaults (extends conventional config)
108
+ DEFAULTS: { extends: ['@commitlint/config-conventional'] },
109
+ };
110
+
111
+ /**
112
+ * Stylelint Configuration Constants
113
+ */
114
+ export const STYLELINT = {
115
+ // Defaults
116
+ DEFAULTS: { extends: ['stylelint-config-standard-scss', 'stylelint-config-property-sort-order-smacss'] },
117
+
118
+ // Plugins
119
+ PLUGINS: { ORDER: 'stylelint-order' },
120
+
121
+ // Configuration
122
+ CONFIG: { customSyntax: 'postcss-scss' },
123
+ };
124
+
125
+ /**
126
+ * TypeScript Configuration Constants
127
+ */
128
+ export const TYPESCRIPT = {
129
+ // Extends from
130
+ EXTENDS: './tsconfig.json',
131
+
132
+ // Core compiler options
133
+ COMPILER_OPTIONS: {
134
+ target: 'ES2020',
135
+ lib: ['ES2020', 'DOM', 'DOM.Iterable'],
136
+ jsx: 'react-jsx',
137
+ module: 'ESNext',
138
+ moduleResolution: 'bundler',
139
+ allowJs: true,
140
+ strict: true,
141
+ skipLibCheck: true,
142
+ esModuleInterop: true,
143
+ resolveJsonModule: true,
144
+ incremental: true,
145
+ },
146
+ };
147
+
148
+ /**
149
+ * JSConfig Configuration Constants
150
+ */
151
+ export const JSCONFIG = {
152
+ // Extends from
153
+ EXTENDS: './jsconfig.json',
154
+
155
+ // Core compiler options
156
+ COMPILER_OPTIONS: {
157
+ target: 'ES2020',
158
+ module: 'ESNext',
159
+ moduleResolution: 'bundler',
160
+ lib: ['ES2020', 'DOM', 'DOM.Iterable'],
161
+ allowJs: true,
162
+ strict: false,
163
+ skipLibCheck: true,
164
+ esModuleInterop: true,
165
+ resolveJsonModule: true,
166
+ },
167
+ };
168
+
169
+ /**
170
+ * Husky Configuration Constants
171
+ */
172
+ export const HUSKY = { DEFAULTS: { version: '9' } };
@@ -6,7 +6,7 @@ describe('eslint/index.js', () => {
6
6
  // Test that the module exports the createConfig function.
7
7
  it('should export createConfig function', async () => {
8
8
  // Dynamically import the index.js module to test its exports.
9
- const module = await import('./index.js');
9
+ const module = await import('../index.js');
10
10
 
11
11
  // Verify that createConfig is a function (used to create ESLint configs).
12
12
  expect(typeof module.createConfig).toBe('function');
@@ -15,7 +15,7 @@ describe('eslint/index.js', () => {
15
15
  // Test that the module exports a default configuration object.
16
16
  it('should export default config', async () => {
17
17
  // Dynamically import the index.js module to test its exports.
18
- const module = await import('./index.js');
18
+ const module = await import('../index.js');
19
19
 
20
20
  // Verify that the default export is defined (should be a base ESLint config object).
21
21
  expect(module.default).toBeDefined();
@@ -23,7 +23,7 @@ describe('eslint/index.js', () => {
23
23
 
24
24
  // Test that the JavaScript config catches basic correctness issues.
25
25
  it('should include recommended JavaScript rules', async () => {
26
- const module = await import('./index.js');
26
+ const module = await import('../index.js');
27
27
  const eslint = new ESLint({
28
28
  overrideConfigFile: true,
29
29
  overrideConfig: module.createConfig({ prettier: false, importOrder: false, jsdoc: false }),
@@ -5,7 +5,7 @@ describe('eslint/next.js', () => {
5
5
  // Test that the module exports the createConfig function.
6
6
  it('should export createConfig function', async () => {
7
7
  // Dynamically import the next.js module to test its exports.
8
- const module = await import('./next.js');
8
+ const module = await import('../next.js');
9
9
 
10
10
  // Verify that createConfig is a function (used to create ESLint config for Next.js).
11
11
  expect(typeof module.createConfig).toBe('function');
@@ -14,7 +14,7 @@ describe('eslint/next.js', () => {
14
14
  // Test that the module exports a default configuration object.
15
15
  it('should export default config', async () => {
16
16
  // Dynamically import the next.js module to test its exports.
17
- const module = await import('./next.js');
17
+ const module = await import('../next.js');
18
18
 
19
19
  // Verify that the default export is defined (should be an ESLint config object).
20
20
  expect(module.default).toBeDefined();
@@ -22,7 +22,7 @@ describe('eslint/next.js', () => {
22
22
 
23
23
  // Test that additional file patterns are applied to the generated config.
24
24
  it('should include additional file patterns from options', async () => {
25
- const module = await import('./next.js');
25
+ const module = await import('../next.js');
26
26
  const result = module.createConfig({ files: ['custom/**/*.tsx'] });
27
27
  const configObject = result.at(-1);
28
28
 
@@ -5,7 +5,7 @@ describe('eslint/react.js', () => {
5
5
  // Test that the module exports the createConfig function.
6
6
  it('should export createConfig function', async () => {
7
7
  // Dynamically import the react.js module to test its exports.
8
- const module = await import('./react.js');
8
+ const module = await import('../react.js');
9
9
 
10
10
  // Verify that createConfig is a function (used to create ESLint config for React).
11
11
  expect(typeof module.createConfig).toBe('function');
@@ -14,7 +14,7 @@ describe('eslint/react.js', () => {
14
14
  // Test that the module exports a default configuration object.
15
15
  it('should export default config', async () => {
16
16
  // Dynamically import the react.js module to test its exports.
17
- const module = await import('./react.js');
17
+ const module = await import('../react.js');
18
18
 
19
19
  // Verify that the default export is defined (should be an ESLint config object).
20
20
  expect(module.default).toBeDefined();
@@ -22,7 +22,7 @@ describe('eslint/react.js', () => {
22
22
 
23
23
  // Test that additional file patterns are applied to the generated config.
24
24
  it('should include additional file patterns from options', async () => {
25
- const module = await import('./react.js');
25
+ const module = await import('../react.js');
26
26
  const result = module.createConfig({ files: ['custom/**/*.tsx'] });
27
27
  const configObject = result.at(-1);
28
28
 
@@ -5,7 +5,7 @@ describe('eslint/typescript.js', () => {
5
5
  // Test that the module exports the createConfig function.
6
6
  it('should export createConfig function', async () => {
7
7
  // Dynamically import the typescript.js module to test its exports.
8
- const module = await import('./typescript.js');
8
+ const module = await import('../typescript.js');
9
9
 
10
10
  // Verify that createConfig is a function (used to create ESLint config for TypeScript).
11
11
  expect(typeof module.createConfig).toBe('function');
@@ -14,7 +14,7 @@ describe('eslint/typescript.js', () => {
14
14
  // Test that the module exports a default configuration object.
15
15
  it('should export default config', async () => {
16
16
  // Dynamically import the typescript.js module to test its exports.
17
- const module = await import('./typescript.js');
17
+ const module = await import('../typescript.js');
18
18
 
19
19
  // Verify that the default export is defined (should be an ESLint config object).
20
20
  expect(module.default).toBeDefined();
@@ -22,7 +22,7 @@ describe('eslint/typescript.js', () => {
22
22
 
23
23
  // Test that additional file patterns are applied to the generated config.
24
24
  it('should include additional file patterns from options', async () => {
25
- const module = await import('./typescript.js');
25
+ const module = await import('../typescript.js');
26
26
  const result = module.createConfig({ files: ['custom/**/*.ts'] });
27
27
  const configObject = result.at(-1);
28
28
 
@@ -5,7 +5,7 @@ describe('eslint/lib/build-config.js', () => {
5
5
  // Test that the module exports the buildConfig function.
6
6
  it('should export buildConfig function', async () => {
7
7
  // Dynamically import the build-config module to test its exports.
8
- const module = await import('./build-config.js');
8
+ const module = await import('../build-config.js');
9
9
 
10
10
  // Verify that buildConfig is a function (used to build ESLint configs).
11
11
  expect(typeof module.buildConfig).toBe('function');
@@ -14,10 +14,10 @@ describe('eslint/lib/build-config.js', () => {
14
14
  // Test that buildConfig returns an array of ESLint config objects.
15
15
  it('should return an array of config objects', async () => {
16
16
  // Dynamically import the build-config module to test its function.
17
- const module = await import('./build-config.js');
17
+ const module = await import('../build-config.js');
18
18
 
19
19
  // Import dependencies needed for the test.
20
- const { files } = await import('./files.js');
20
+ const { files } = await import('../files.js');
21
21
 
22
22
  // Call buildConfig with test parameters (JS-only files, empty options).
23
23
  const result = module.buildConfig({ files: files.withoutTs, options: {} });
@@ -28,8 +28,8 @@ describe('eslint/lib/build-config.js', () => {
28
28
 
29
29
  // Test that buildConfig handles flat config arrays and objects.
30
30
  it('should handle flat config arrays and objects', async () => {
31
- const module = await import('./build-config.js');
32
- const { files } = await import('./files.js');
31
+ const module = await import('../build-config.js');
32
+ const { files } = await import('../files.js');
33
33
 
34
34
  // A flat config array (simulating eslint-config-next export)
35
35
  const flatConfigArray = [{ name: 'test-flat-config', plugins: {}, rules: { 'no-console': 'warn' } }];
@@ -52,8 +52,8 @@ describe('eslint/lib/build-config.js', () => {
52
52
 
53
53
  // Test that buildConfig sets import-x/resolver-next when importOrder is enabled.
54
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');
55
+ const module = await import('../build-config.js');
56
+ const { files } = await import('../files.js');
57
57
 
58
58
  const result = module.buildConfig({ files: files.withoutTs, options: { importOrder: true } });
59
59
 
@@ -68,8 +68,8 @@ describe('eslint/lib/build-config.js', () => {
68
68
 
69
69
  // Test that buildConfig omits import-x/resolver-next when importOrder is disabled.
70
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');
71
+ const module = await import('../build-config.js');
72
+ const { files } = await import('../files.js');
73
73
 
74
74
  const result = module.buildConfig({ files: files.withoutTs, options: { importOrder: false } });
75
75
 
@@ -80,8 +80,8 @@ describe('eslint/lib/build-config.js', () => {
80
80
 
81
81
  // Test that buildConfig includes .gitignore patterns via includeIgnoreFile.
82
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');
83
+ const module = await import('../build-config.js');
84
+ const { files } = await import('../files.js');
85
85
 
86
86
  const result = module.buildConfig({ files: files.withoutTs, options: {} });
87
87
 
@@ -5,7 +5,7 @@ describe('eslint/lib/files.js', () => {
5
5
  // Test that the module exports a files object with TypeScript and non-TypeScript file arrays.
6
6
  it('should export files object with withTs and withoutTs arrays', async () => {
7
7
  // Dynamically import the files module to test its exports.
8
- const module = await import('./files.js');
8
+ const module = await import('../files.js');
9
9
 
10
10
  // Verify that files is an object.
11
11
  expect(typeof module.files).toBe('object');
@@ -20,7 +20,7 @@ describe('eslint/lib/files.js', () => {
20
20
  // Test that the file patterns are correctly defined for TypeScript and JavaScript files.
21
21
  it('should have correct file patterns', async () => {
22
22
  // Dynamically import the files module to test its exports.
23
- const module = await import('./files.js');
23
+ const module = await import('../files.js');
24
24
 
25
25
  // Verify that withTs array contains the pattern for TypeScript files.
26
26
  expect(module.files.withTs).toContain('**/*.{js,jsx,mjs,cjs,ts,tsx}');