@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.
- package/README.md +39 -0
- package/package.json +17 -20
- package/src/__tests__/config-constants.test.js +111 -0
- package/src/{index.test.js → __tests__/index.test.js} +1 -1
- package/src/commitlint/{index.test.js → __tests__/index.test.js} +5 -5
- package/src/commitlint/index.js +3 -1
- package/src/config-constants.js +172 -0
- package/src/eslint/{index.test.js → __tests__/index.test.js} +3 -3
- package/src/eslint/{next.test.js → __tests__/next.test.js} +3 -3
- package/src/eslint/{react.test.js → __tests__/react.test.js} +3 -3
- package/src/eslint/{typescript.test.js → __tests__/typescript.test.js} +3 -3
- package/src/eslint/lib/{build-config.test.js → __tests__/build-config.test.js} +11 -11
- package/src/eslint/lib/{files.test.js → __tests__/files.test.js} +2 -2
- package/src/eslint/lib/{ignores.test.js → __tests__/ignores.test.js} +3 -3
- package/src/eslint/lib/{index.test.js → __tests__/index.test.js} +2 -2
- package/src/eslint/lib/{language-options.test.js → __tests__/language-options.test.js} +2 -2
- package/src/eslint/lib/{rules.test.js → __tests__/rules.test.js} +1 -1
- package/src/eslint/lib/{setup.test.js → __tests__/setup.test.js} +1 -1
- package/src/eslint/lib/build-config.js +11 -110
- package/src/eslint/lib/files.js +3 -1
- package/src/eslint/lib/plugin-helpers/__tests__/enabled-plugins.test.js +49 -0
- package/src/eslint/lib/plugin-helpers/__tests__/fixup.test.js +48 -0
- package/src/eslint/lib/plugin-helpers/__tests__/flatten.test.js +51 -0
- package/src/eslint/lib/plugin-helpers/__tests__/parser.test.js +78 -0
- package/src/eslint/lib/plugin-helpers/__tests__/strip.test.js +70 -0
- package/src/eslint/lib/plugin-helpers/enabled-plugins.js +26 -0
- package/src/eslint/lib/plugin-helpers/fixup.js +34 -0
- package/src/eslint/lib/plugin-helpers/flatten.js +31 -0
- package/src/eslint/lib/plugin-helpers/index.js +18 -0
- package/src/eslint/lib/plugin-helpers/parser.js +33 -0
- package/src/eslint/lib/plugin-helpers/strip.js +45 -0
- package/src/gulp-smacss/{index.test.js → __tests__/index.test.js} +2 -2
- package/src/gulp-smacss/index.js +5 -0
- package/src/jsconfig/{index.test.js → __tests__/index.test.js} +3 -3
- package/src/lib/__tests__/config-utils.test.js +145 -0
- package/src/lib/__tests__/validators.test.js +229 -0
- package/src/lib/config-utils.js +187 -0
- package/src/lib/validators.js +225 -0
- package/src/next-sitemap/{index.test.js → __tests__/index.test.js} +31 -5
- package/src/next-sitemap/index.js +22 -8
- package/src/prettier/{index.test.js → __tests__/index.test.js} +4 -4
- package/src/prettier/index.js +11 -47
- package/src/stylelint/{index.test.js → __tests__/index.test.js} +5 -5
- package/src/stylelint/index.js +4 -2
- 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.
|
|
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
|
|
71
|
-
"@commitlint/config-conventional": "^21.
|
|
72
|
-
"@commitlint/types": "^21.
|
|
73
|
-
"@typescript-eslint/parser": "^8.
|
|
74
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
75
|
-
"@vitest/coverage-v8": "^4.1.
|
|
76
|
-
"eslint": "^10.
|
|
77
|
-
"eslint-config-next": "^16.
|
|
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.
|
|
80
|
-
"eslint-plugin-jsdoc": "^63.
|
|
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.
|
|
85
|
+
"globals": "^17.9.0",
|
|
86
86
|
"husky": "^9.1.7",
|
|
87
|
-
"next": "^16.
|
|
88
|
-
"prettier": "^3.
|
|
87
|
+
"next": "^16.3.0",
|
|
88
|
+
"prettier": "^3.9.6",
|
|
89
89
|
"@prettier/plugin-xml": "^3.4.2",
|
|
90
|
-
"release-it": "^
|
|
90
|
+
"release-it": "^21.0.1",
|
|
91
91
|
"typescript": "^6.0.3",
|
|
92
|
-
"typescript-eslint": "^8.
|
|
93
|
-
"vitest": "^4.1.
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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();
|
package/src/commitlint/index.js
CHANGED
|
@@ -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
|
-
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
17
|
+
const module = await import('../build-config.js');
|
|
18
18
|
|
|
19
19
|
// Import dependencies needed for the test.
|
|
20
|
-
const { files } = await import('
|
|
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('
|
|
32
|
-
const { files } = await import('
|
|
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('
|
|
56
|
-
const { files } = await import('
|
|
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('
|
|
72
|
-
const { files } = await import('
|
|
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('
|
|
84
|
-
const { files } = await import('
|
|
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('
|
|
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('
|
|
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}');
|