@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 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();