@noxickon/codex 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -0
- package/eslint/react.config.js +226 -0
- package/package.json +37 -0
- package/prettier.config.js +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# @noxickon/codex
|
|
2
|
+
|
|
3
|
+
Shared ESLint and Prettier configuration for noxickon projects.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
npm install --save-dev @noxickon/codex
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
### ESLint
|
|
12
|
+
|
|
13
|
+
##### Basic usage (React projects):
|
|
14
|
+
|
|
15
|
+
###### eslint.config.js
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
import { createReactConfig } from '@noxickon/codex/eslint/react';
|
|
19
|
+
|
|
20
|
+
export default createReactConfig();
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
##### Custom Tailwind CSS path:
|
|
24
|
+
|
|
25
|
+
###### eslint.config.js
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
import { createReactConfig } from '@noxickon/codex/eslint/react';
|
|
29
|
+
|
|
30
|
+
export default createReactConfig({
|
|
31
|
+
tailwindEntryPoint: './styles/tailwind.css',
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
##### Disable Tailwind plugin:
|
|
36
|
+
|
|
37
|
+
###### eslint.config.js
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
import { createReactConfig } from '@noxickon/codex/eslint/react';
|
|
41
|
+
|
|
42
|
+
export default createReactConfig({
|
|
43
|
+
tailwindEntryPoint: null,
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Prettier
|
|
48
|
+
|
|
49
|
+
##### Basic usage:
|
|
50
|
+
|
|
51
|
+
###### prettier.config.js
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
import { createPrettierConfig } from '@noxickon/codex/prettier';
|
|
55
|
+
|
|
56
|
+
export default createPrettierConfig();
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
##### Custom Tailwind configuration:
|
|
60
|
+
|
|
61
|
+
###### prettier.config.js
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
import { createPrettierConfig } from '@noxickon/codex/prettier';
|
|
65
|
+
|
|
66
|
+
export default createPrettierConfig({
|
|
67
|
+
tailwindStylesheet: './styles/tailwind.css',
|
|
68
|
+
tailwindFunctions: ['twMerge', 'twJoin', 'clsx', 'cn', 'customHelper'],
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Configuration Options
|
|
73
|
+
|
|
74
|
+
### ESLint (React)
|
|
75
|
+
|
|
76
|
+
| Option | Type | Default | Description |
|
|
77
|
+
| ------------------ | -------------- | -------------------- | ---------------------------------------------------------------- |
|
|
78
|
+
| tailwindEntryPoint | string or null | './src/tailwind.css' | Path to your Tailwind CSS file. Set to null to disable Tailwind. |
|
|
79
|
+
|
|
80
|
+
### Prettier
|
|
81
|
+
|
|
82
|
+
| Option | Type | Default | Description |
|
|
83
|
+
| ------------------ | -------- | ----------------------------------- | --------------------------------------------------- |
|
|
84
|
+
| tailwindStylesheet | string | './src/tailwind.css' | Path to your Tailwind CSS file for class sorting. |
|
|
85
|
+
| tailwindFunctions | string[] | ['twMerge', 'twJoin', 'clsx', 'cn'] | Custom helper functions for Tailwind class sorting. |
|
|
86
|
+
|
|
87
|
+
## Included Plugins
|
|
88
|
+
|
|
89
|
+
### ESLint
|
|
90
|
+
|
|
91
|
+
- TypeScript ESLint
|
|
92
|
+
- React Hooks
|
|
93
|
+
- React Compiler
|
|
94
|
+
- React Refresh (Vite)
|
|
95
|
+
- JSX Accessibility (a11y)
|
|
96
|
+
- Unicorn (Modern JS/TS best practices)
|
|
97
|
+
- Perfectionist (Auto-sorting)
|
|
98
|
+
- Better Tailwind CSS
|
|
99
|
+
- Unused Imports
|
|
100
|
+
- Sort Destructure Keys
|
|
101
|
+
|
|
102
|
+
### Prettier
|
|
103
|
+
|
|
104
|
+
- Prettier Plugin Tailwind CSS
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
MIT
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import js from '@eslint/js';
|
|
2
|
+
import eslintConfigPrettier from 'eslint-config-prettier';
|
|
3
|
+
import betterTailwind from 'eslint-plugin-better-tailwindcss';
|
|
4
|
+
import jsxA11y from 'eslint-plugin-jsx-a11y';
|
|
5
|
+
import perfectionist from 'eslint-plugin-perfectionist';
|
|
6
|
+
import reactCompiler from 'eslint-plugin-react-compiler';
|
|
7
|
+
import reactHooks from 'eslint-plugin-react-hooks';
|
|
8
|
+
import reactRefresh from 'eslint-plugin-react-refresh';
|
|
9
|
+
import sortDestructureKeys from 'eslint-plugin-sort-destructure-keys';
|
|
10
|
+
import unicorn from 'eslint-plugin-unicorn';
|
|
11
|
+
import unusedImports from 'eslint-plugin-unused-imports';
|
|
12
|
+
import globals from 'globals';
|
|
13
|
+
import tseslint from 'typescript-eslint';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create ESLint config for React projects
|
|
17
|
+
* @param {Object} options
|
|
18
|
+
* @param {string} [options.tailwindEntryPoint] - Path to Tailwind CSS file (default: './src/tailwind.css')
|
|
19
|
+
*/
|
|
20
|
+
export function createReactConfig({ tailwindEntryPoint = './src/tailwind.css' } = {}) {
|
|
21
|
+
return [
|
|
22
|
+
{
|
|
23
|
+
ignores: ['dist', 'storybook-static', 'coverage', 'node_modules'],
|
|
24
|
+
},
|
|
25
|
+
js.configs.recommended,
|
|
26
|
+
...tseslint.configs.recommended,
|
|
27
|
+
{
|
|
28
|
+
files: ['**/*.{ts,tsx,js,jsx}'],
|
|
29
|
+
languageOptions: {
|
|
30
|
+
ecmaVersion: 2022,
|
|
31
|
+
globals: globals.browser,
|
|
32
|
+
},
|
|
33
|
+
plugins: {
|
|
34
|
+
'better-tailwind': betterTailwind,
|
|
35
|
+
'jsx-a11y': jsxA11y,
|
|
36
|
+
perfectionist,
|
|
37
|
+
'react-compiler': reactCompiler,
|
|
38
|
+
'react-hooks': reactHooks,
|
|
39
|
+
'react-refresh': reactRefresh,
|
|
40
|
+
'sort-destructure-keys': sortDestructureKeys,
|
|
41
|
+
unicorn,
|
|
42
|
+
'unused-imports': unusedImports,
|
|
43
|
+
},
|
|
44
|
+
settings: {
|
|
45
|
+
'better-tailwindcss': {
|
|
46
|
+
entryPoint: tailwindEntryPoint,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
rules: {
|
|
50
|
+
// React
|
|
51
|
+
...reactHooks.configs.recommended.rules,
|
|
52
|
+
'react-compiler/react-compiler': 'error',
|
|
53
|
+
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
|
|
54
|
+
|
|
55
|
+
// Tailwind - modern shorthand enforcement
|
|
56
|
+
'better-tailwind/enforce-shorthand-classes': 'warn',
|
|
57
|
+
'better-tailwind/no-unnecessary-whitespace': 'warn',
|
|
58
|
+
'better-tailwind/no-duplicate-classes': 'warn',
|
|
59
|
+
'better-tailwind/no-unregistered-classes': 'off',
|
|
60
|
+
|
|
61
|
+
// Unicorn - modern JS/TS best practices
|
|
62
|
+
...unicorn.configs.recommended.rules,
|
|
63
|
+
|
|
64
|
+
// Unicorn Overrides - React-friendly but modern
|
|
65
|
+
'unicorn/prevent-abbreviations': [
|
|
66
|
+
'error',
|
|
67
|
+
{
|
|
68
|
+
checkFilenames: false,
|
|
69
|
+
allowList: {
|
|
70
|
+
// React Standards (Type names):
|
|
71
|
+
Props: true, // ButtonProps, OxButtonProps
|
|
72
|
+
Ref: true, // ForwardRef types
|
|
73
|
+
|
|
74
|
+
// React Standards (runtime):
|
|
75
|
+
props: true, // function Component({ props })
|
|
76
|
+
ref: true, // useRef, forwardRef
|
|
77
|
+
prev: true, // setState((prev) => ...)
|
|
78
|
+
|
|
79
|
+
// Standard Loop Counters:
|
|
80
|
+
i: true,
|
|
81
|
+
j: true,
|
|
82
|
+
k: true,
|
|
83
|
+
|
|
84
|
+
// Node.js/Backend Standards:
|
|
85
|
+
db: true,
|
|
86
|
+
env: true,
|
|
87
|
+
req: true,
|
|
88
|
+
res: true,
|
|
89
|
+
|
|
90
|
+
// Context/Function:
|
|
91
|
+
ctx: true,
|
|
92
|
+
fn: true,
|
|
93
|
+
args: true,
|
|
94
|
+
param: true,
|
|
95
|
+
params: true,
|
|
96
|
+
},
|
|
97
|
+
replacements: {
|
|
98
|
+
// Important: Event handlers must be descriptive!
|
|
99
|
+
e: {
|
|
100
|
+
event: true,
|
|
101
|
+
},
|
|
102
|
+
evt: {
|
|
103
|
+
event: true,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
'unicorn/catch-error-name': [
|
|
109
|
+
'error',
|
|
110
|
+
{
|
|
111
|
+
name: 'error', // catch (error) instead of catch (err)
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
|
|
115
|
+
// Too opinionated - disabled:
|
|
116
|
+
'unicorn/no-null': 'off', // null has semantic meaning
|
|
117
|
+
'unicorn/no-array-reduce': 'off', // reduce is sometimes elegant
|
|
118
|
+
'unicorn/no-array-for-each': 'off', // forEach is fine
|
|
119
|
+
'unicorn/prefer-top-level-await': 'off', // Not supported everywhere
|
|
120
|
+
'unicorn/filename-case': 'off', // React = PascalCase
|
|
121
|
+
'unicorn/switch-case-braces': 'off', // Too strict
|
|
122
|
+
'unicorn/no-negated-condition': 'off', // Sometimes more readable
|
|
123
|
+
'unicorn/prefer-ternary': 'off', // if/else sometimes clearer
|
|
124
|
+
|
|
125
|
+
// Modern best practices - as warnings instead of errors:
|
|
126
|
+
'unicorn/prefer-query-selector': 'warn', // querySelector is more modern
|
|
127
|
+
'unicorn/prefer-global-this': 'warn', // globalThis is ES2020 standard
|
|
128
|
+
'unicorn/import-style': 'off', // node:path vs path - both ok
|
|
129
|
+
'unicorn/no-useless-undefined': 'off', // Explicit undefined is sometimes clearer
|
|
130
|
+
|
|
131
|
+
// Perfectionist - auto-sorting
|
|
132
|
+
'perfectionist/sort-interfaces': ['error'],
|
|
133
|
+
'perfectionist/sort-object-types': ['error'],
|
|
134
|
+
'perfectionist/sort-named-imports': ['error'],
|
|
135
|
+
'perfectionist/sort-named-exports': ['error'],
|
|
136
|
+
'perfectionist/sort-imports': [
|
|
137
|
+
'error',
|
|
138
|
+
{
|
|
139
|
+
type: 'alphabetical',
|
|
140
|
+
order: 'asc',
|
|
141
|
+
ignoreCase: true,
|
|
142
|
+
newlinesBetween: 'always',
|
|
143
|
+
groups: [
|
|
144
|
+
['builtin-type', 'builtin'],
|
|
145
|
+
'frameworks',
|
|
146
|
+
['external-type', 'external'],
|
|
147
|
+
['internal-type', 'internal'],
|
|
148
|
+
['parent-type', 'parent'],
|
|
149
|
+
['sibling-type', 'sibling'],
|
|
150
|
+
['index-type', 'index'],
|
|
151
|
+
],
|
|
152
|
+
customGroups: [
|
|
153
|
+
{
|
|
154
|
+
groupName: 'frameworks',
|
|
155
|
+
elementNamePattern: ['^vite$', '^@vitejs/', '^react$', '^react-dom$'],
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
'perfectionist/sort-jsx-props': [
|
|
161
|
+
'error',
|
|
162
|
+
{
|
|
163
|
+
type: 'alphabetical',
|
|
164
|
+
order: 'asc',
|
|
165
|
+
ignoreCase: true,
|
|
166
|
+
groups: ['id', 'unknown', 'callback'],
|
|
167
|
+
customGroups: [
|
|
168
|
+
{
|
|
169
|
+
groupName: 'id',
|
|
170
|
+
elementNamePattern: '^id$',
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
groupName: 'callback',
|
|
174
|
+
elementNamePattern: '^on.+',
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
|
|
180
|
+
// Destructuring
|
|
181
|
+
'sort-destructure-keys/sort-destructure-keys': ['error', { caseSensitive: true }],
|
|
182
|
+
|
|
183
|
+
// TypeScript
|
|
184
|
+
'@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports' }],
|
|
185
|
+
'@typescript-eslint/no-unused-vars': 'off',
|
|
186
|
+
|
|
187
|
+
// Unused Imports - auto-cleanup
|
|
188
|
+
'unused-imports/no-unused-imports': 'error',
|
|
189
|
+
'unused-imports/no-unused-vars': [
|
|
190
|
+
'warn',
|
|
191
|
+
{
|
|
192
|
+
argsIgnorePattern: '^_',
|
|
193
|
+
vars: 'all',
|
|
194
|
+
varsIgnorePattern: '^_',
|
|
195
|
+
args: 'after-used',
|
|
196
|
+
},
|
|
197
|
+
],
|
|
198
|
+
|
|
199
|
+
// Accessibility - important for UI library!
|
|
200
|
+
'jsx-a11y/alt-text': 'warn',
|
|
201
|
+
'jsx-a11y/aria-props': 'warn',
|
|
202
|
+
'jsx-a11y/aria-proptypes': 'warn',
|
|
203
|
+
'jsx-a11y/aria-unsupported-elements': 'warn',
|
|
204
|
+
'jsx-a11y/role-has-required-aria-props': 'warn',
|
|
205
|
+
'jsx-a11y/role-supports-aria-props': 'warn',
|
|
206
|
+
|
|
207
|
+
// Import Restrictions - consistent absolute imports
|
|
208
|
+
'no-restricted-imports': [
|
|
209
|
+
'error',
|
|
210
|
+
{
|
|
211
|
+
patterns: [
|
|
212
|
+
{
|
|
213
|
+
group: ['../*'],
|
|
214
|
+
message:
|
|
215
|
+
'Relative parent imports are not allowed. Use absolute imports with @ instead.',
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
eslintConfigPrettier,
|
|
223
|
+
];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export default createReactConfig();
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@noxickon/codex",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Shared ESLint & Prettier configuration for noxickon projects",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
"./prettier": "./prettier.config.js",
|
|
8
|
+
"./eslint/react": "./eslint/react.config.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"eslint",
|
|
12
|
+
"prettier.config.js"
|
|
13
|
+
],
|
|
14
|
+
"keywords": [
|
|
15
|
+
"eslint",
|
|
16
|
+
"prettier",
|
|
17
|
+
"config"
|
|
18
|
+
],
|
|
19
|
+
"author": "noxickon",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@typescript-eslint/eslint-plugin": "^8.46.4",
|
|
23
|
+
"@typescript-eslint/parser": "^8.46.4",
|
|
24
|
+
"eslint": "^9.39.1",
|
|
25
|
+
"eslint-config-prettier": "^10.1.8",
|
|
26
|
+
"eslint-plugin-better-tailwindcss": "^3.7.10",
|
|
27
|
+
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
28
|
+
"eslint-plugin-react": "^7.37.5",
|
|
29
|
+
"eslint-plugin-react-compiler": "^19.1.0-rc.2",
|
|
30
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
31
|
+
"eslint-plugin-sort-destructure-keys": "^2.0.0",
|
|
32
|
+
"eslint-plugin-unicorn": "^62.0.0",
|
|
33
|
+
"prettier": "^3.6.2",
|
|
34
|
+
"prettier-plugin-tailwindcss": "^0.7.1",
|
|
35
|
+
"typescript-eslint": "^8.46.4"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create Prettier config for noxickon projects
|
|
3
|
+
* @param {Object} options
|
|
4
|
+
* @param {string} [options.tailwindStylesheet] - Path to Tailwind CSS file (default: './src/tailwind.css')
|
|
5
|
+
* @param {string[]} [options.tailwindFunctions] - Custom Tailwind helper functions (default: ['twMerge', 'twJoin', 'clsx', 'cn'])
|
|
6
|
+
*/
|
|
7
|
+
export function createPrettierConfig({
|
|
8
|
+
tailwindStylesheet = './src/tailwind.css',
|
|
9
|
+
tailwindFunctions = ['twMerge', 'twJoin', 'clsx', 'cn'],
|
|
10
|
+
} = {}) {
|
|
11
|
+
return {
|
|
12
|
+
trailingComma: 'es5',
|
|
13
|
+
useTabs: false,
|
|
14
|
+
tabWidth: 2,
|
|
15
|
+
semi: true,
|
|
16
|
+
singleQuote: true,
|
|
17
|
+
quoteProps: 'as-needed',
|
|
18
|
+
jsxSingleQuote: false,
|
|
19
|
+
bracketSameLine: false,
|
|
20
|
+
printWidth: 100,
|
|
21
|
+
bracketSpacing: true,
|
|
22
|
+
arrowParens: 'always',
|
|
23
|
+
endOfLine: 'lf',
|
|
24
|
+
plugins: ['prettier-plugin-tailwindcss'],
|
|
25
|
+
tailwindStylesheet,
|
|
26
|
+
tailwindFunctions,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default createPrettierConfig();
|