@higuma/eslint-config 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # @higuma/eslint-config
2
+
3
+ Shared ESLint flat configs (ESLint 9+) for Higuma Soft projects.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # All projects need these
9
+ npm install --save-dev @higuma/eslint-config eslint typescript-eslint @eslint/js globals \
10
+ eslint-plugin-simple-import-sort eslint-plugin-unused-imports
11
+
12
+ # React / Next.js projects also need
13
+ npm install --save-dev eslint-plugin-react eslint-plugin-react-hooks
14
+
15
+ # Next.js projects also need
16
+ npm install --save-dev @next/eslint-plugin-next
17
+ ```
18
+
19
+ ## Configs
20
+
21
+ | Import | Use for |
22
+ |--------|---------|
23
+ | `@higuma/eslint-config/base` | Any TS project — libraries, Node, CLI |
24
+ | `@higuma/eslint-config/react` | React SPA |
25
+ | `@higuma/eslint-config/next` | Next.js app |
26
+
27
+ ## Usage
28
+
29
+ ### Library (registrie)
30
+
31
+ ```js
32
+ // eslint.config.mjs
33
+ import base from '@higuma/eslint-config/base';
34
+ export default base;
35
+ ```
36
+
37
+ ### React SPA
38
+
39
+ ```js
40
+ // eslint.config.mjs
41
+ import react from '@higuma/eslint-config/react';
42
+ export default react;
43
+ ```
44
+
45
+ ### Next.js
46
+
47
+ ```js
48
+ // eslint.config.mjs
49
+ import next from '@higuma/eslint-config/next';
50
+ export default next;
51
+ ```
52
+
53
+ ### With overrides
54
+
55
+ ```js
56
+ // eslint.config.mjs
57
+ import base from '@higuma/eslint-config/base';
58
+
59
+ export default [
60
+ ...base,
61
+ {
62
+ rules: {
63
+ 'no-console': 'warn', // downgrade for this project
64
+ },
65
+ },
66
+ ];
67
+ ```
68
+
69
+ ## Rules included in all configs
70
+
71
+ | Rule | Level |
72
+ |------|-------|
73
+ | `simple-import-sort/imports` | error |
74
+ | `unused-imports/no-unused-imports` | error |
75
+ | `@typescript-eslint/no-explicit-any` | error |
76
+ | `@typescript-eslint/no-unused-vars` | error |
77
+ | `@typescript-eslint/no-non-null-assertion` | warn |
78
+ | `@typescript-eslint/consistent-type-imports` | error |
79
+ | `@typescript-eslint/no-floating-promises` | error |
80
+ | `no-console` | error |
81
+ | `no-var` | error |
82
+ | `prefer-const` | error |
83
+ | `eqeqeq` | error |
84
+ | `consistent-return` | error |
85
+ | `no-shadow` | error |
86
+
87
+ Test files (`*.test.ts`, `*.spec.ts`, `test/**`) get `no-explicit-any`, `no-non-null-assertion`, `no-floating-promises`, and `no-console` turned off.
package/base.js ADDED
@@ -0,0 +1,80 @@
1
+ // @higuma/eslint-config/base
2
+ // Strict TypeScript flat config for any project (library, Node, browser).
3
+ // Consumers: registrie and any non-React project.
4
+
5
+ import js from '@eslint/js';
6
+ import globals from 'globals';
7
+ import tseslint from 'typescript-eslint';
8
+ import simpleImportSort from 'eslint-plugin-simple-import-sort';
9
+ import unusedImports from 'eslint-plugin-unused-imports';
10
+
11
+ /** @type {import('eslint').Linter.Config[]} */
12
+ const base = tseslint.config(
13
+ // Global ignores
14
+ {
15
+ ignores: ['dist/**', 'node_modules/**', '.next/**', 'coverage/**'],
16
+ },
17
+
18
+ // ESLint + TS recommended baseline
19
+ js.configs.recommended,
20
+ ...tseslint.configs.recommended,
21
+
22
+ // Main rules
23
+ {
24
+ files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
25
+ languageOptions: {
26
+ globals: {
27
+ ...globals.node,
28
+ },
29
+ },
30
+ plugins: {
31
+ 'simple-import-sort': simpleImportSort,
32
+ 'unused-imports': unusedImports,
33
+ },
34
+ rules: {
35
+ // — Imports —
36
+ 'simple-import-sort/imports': 'error',
37
+ 'simple-import-sort/exports': 'error',
38
+ 'unused-imports/no-unused-imports': 'error',
39
+
40
+ // — TypeScript —
41
+ '@typescript-eslint/no-explicit-any': 'error',
42
+ '@typescript-eslint/no-unused-vars': [
43
+ 'error',
44
+ {
45
+ argsIgnorePattern: '^_',
46
+ varsIgnorePattern: '^_',
47
+ caughtErrorsIgnorePattern: '^_',
48
+ },
49
+ ],
50
+ '@typescript-eslint/no-non-null-assertion': 'warn',
51
+ '@typescript-eslint/consistent-type-imports': [
52
+ 'error',
53
+ { prefer: 'type-imports', fixStyle: 'inline-type-imports' },
54
+ ],
55
+ '@typescript-eslint/no-floating-promises': 'error',
56
+ '@typescript-eslint/consistent-type-definitions': ['error', 'type'],
57
+
58
+ // — General —
59
+ 'no-console': 'error',
60
+ 'no-var': 'error',
61
+ 'prefer-const': 'error',
62
+ eqeqeq: ['error', 'always'],
63
+ 'consistent-return': 'error',
64
+ 'no-shadow': 'error',
65
+ },
66
+ },
67
+
68
+ // Test files — relaxed
69
+ {
70
+ files: ['**/*.test.ts', '**/*.spec.ts', 'test/**/*.ts', '**/*.test.tsx'],
71
+ rules: {
72
+ '@typescript-eslint/no-explicit-any': 'off',
73
+ '@typescript-eslint/no-non-null-assertion': 'off',
74
+ '@typescript-eslint/no-floating-promises': 'off',
75
+ 'no-console': 'off',
76
+ },
77
+ }
78
+ );
79
+
80
+ export default base;
package/index.js ADDED
@@ -0,0 +1,7 @@
1
+ // @higuma/eslint-config
2
+ // Re-exports all configs for convenience.
3
+ // Prefer named imports: import base from '@higuma/eslint-config/base'
4
+
5
+ export { default as base } from './base.js';
6
+ export { default as react } from './react.js';
7
+ export { default as next } from './next.js';
package/next.js ADDED
@@ -0,0 +1,34 @@
1
+ // @higuma/eslint-config/next
2
+ // Extends react with Next.js-specific rules.
3
+ // Use for: Next.js app projects.
4
+
5
+ import nextPlugin from '@next/eslint-plugin-next';
6
+ import tseslint from 'typescript-eslint';
7
+ import react from './react.js';
8
+
9
+ /** @type {import('eslint').Linter.Config[]} */
10
+ const next = tseslint.config(
11
+ ...react,
12
+
13
+ {
14
+ files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
15
+ plugins: {
16
+ '@next/next': nextPlugin,
17
+ },
18
+ rules: {
19
+ // Core Next.js rules — all recommended ones as errors
20
+ ...Object.fromEntries(
21
+ Object.entries(nextPlugin.configs.recommended.rules ?? {}).map(
22
+ ([rule, _]) => [rule, 'error']
23
+ )
24
+ ),
25
+
26
+ // Next.js specific overrides
27
+ '@next/next/no-html-link-for-pages': 'error',
28
+ '@next/next/no-img-element': 'error', // enforce next/image
29
+ '@next/next/no-sync-scripts': 'error',
30
+ },
31
+ }
32
+ );
33
+
34
+ export default next;
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@higuma/eslint-config",
3
+ "version": "0.1.0",
4
+ "description": "Shared ESLint flat configs for Higuma Soft projects.",
5
+ "keywords": ["eslint", "eslint-config", "typescript", "higuma"],
6
+ "author": "Higuma Soft",
7
+ "license": "MIT",
8
+ "type": "module",
9
+ "main": "./index.js",
10
+ "exports": {
11
+ ".": "./index.js",
12
+ "./base": "./base.js",
13
+ "./react": "./react.js",
14
+ "./next": "./next.js"
15
+ },
16
+ "files": [
17
+ "*.js",
18
+ "README.md"
19
+ ],
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "peerDependencies": {
24
+ "@eslint/js": "^9.0.0",
25
+ "@next/eslint-plugin-next": "^14.0.0",
26
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
27
+ "@typescript-eslint/parser": "^8.0.0",
28
+ "eslint": "^9.0.0",
29
+ "eslint-plugin-react": "^7.0.0",
30
+ "eslint-plugin-react-hooks": "^5.0.0",
31
+ "eslint-plugin-simple-import-sort": "^12.0.0",
32
+ "eslint-plugin-unused-imports": "^4.0.0",
33
+ "globals": "^15.0.0",
34
+ "typescript-eslint": "^8.0.0"
35
+ },
36
+ "peerDependenciesMeta": {
37
+ "@next/eslint-plugin-next": {
38
+ "optional": true
39
+ },
40
+ "eslint-plugin-react": {
41
+ "optional": true
42
+ },
43
+ "eslint-plugin-react-hooks": {
44
+ "optional": true
45
+ }
46
+ }
47
+ }
package/react.js ADDED
@@ -0,0 +1,50 @@
1
+ // @higuma/eslint-config/react
2
+ // Extends base with React-specific rules.
3
+ // Use for: React SPA projects.
4
+
5
+ import globals from 'globals';
6
+ import reactPlugin from 'eslint-plugin-react';
7
+ import reactHooks from 'eslint-plugin-react-hooks';
8
+ import tseslint from 'typescript-eslint';
9
+ import base from './base.js';
10
+
11
+ /** @type {import('eslint').Linter.Config[]} */
12
+ const react = tseslint.config(
13
+ ...base,
14
+
15
+ {
16
+ files: ['**/*.tsx', '**/*.jsx'],
17
+ languageOptions: {
18
+ globals: {
19
+ ...globals.browser,
20
+ },
21
+ parserOptions: {
22
+ ecmaFeatures: { jsx: true },
23
+ },
24
+ },
25
+ plugins: {
26
+ react: reactPlugin,
27
+ 'react-hooks': reactHooks,
28
+ },
29
+ settings: {
30
+ react: {
31
+ // Automatically detect React version
32
+ version: 'detect',
33
+ },
34
+ },
35
+ rules: {
36
+ // Hooks
37
+ 'react-hooks/rules-of-hooks': 'error',
38
+ 'react-hooks/exhaustive-deps': 'error',
39
+
40
+ // Props
41
+ 'react/no-unused-prop-types': 'error',
42
+
43
+ // React 17+ — no need to import React in scope
44
+ 'react/react-in-jsx-scope': 'off',
45
+ 'react/jsx-uses-react': 'off',
46
+ },
47
+ }
48
+ );
49
+
50
+ export default react;