diff --git a/README.md b/README.md index d099426..f144ebc 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,10 @@ My configuration for the ESLint / Prettier / TypeScript My CSpell configuration for general projects. - [`packages/eslint-config-base`](packages/eslint-config-base/README.md): My ESLint configuration for general projects. -- [`packages/eslint-config-react`](packages/eslint-config-base/README.md): +- [`packages/eslint-config-react`](packages/eslint-config-react/README.md): My ESLint configuration for React projects. +- [`packages/eslint-config-solid`](packages/eslint-config-solid/README.md): + My ESLint configuration for Solid.js projects. - [`packages/lint-staged-config`](packages/lint-staged-config/README.md): My lint-staged configuration for general projects. - [`packages/markdownlint-config`](packages/markdownlint-config/README.md): diff --git a/package.json b/package.json index 155b00a..24c3982 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "@kurone-kito/commitlint-config": "workspace:^", "@kurone-kito/cspell-config": "workspace:^", "@kurone-kito/eslint-config-base": "workspace:^", - "@kurone-kito/eslint-config-react": "workspace:^", "@kurone-kito/lint-staged-config": "workspace:^", "@kurone-kito/markdownlint-config": "workspace:^", "@kurone-kito/prettier-config": "workspace:^", diff --git a/packages/eslint-config-solid/README.md b/packages/eslint-config-solid/README.md new file mode 100644 index 0000000..0820db2 --- /dev/null +++ b/packages/eslint-config-solid/README.md @@ -0,0 +1,22 @@ +# `@kurone-kito/eslint-config-solid` + +My ESLint configuration for Solid.js projects. + +## Usage + +First, install this package and its peer dependencies: + +```sh +npm install --save-dev @kurone-kito/eslint-config-solid eslint +``` + +Then, create a `eslint.config.mjs` file. +If exists, merge the following configuration into it: + +```js +export { default } from '@kurone-kito/eslint-config-solid'; +``` + +## License + +MIT diff --git a/packages/eslint-config-solid/package.json b/packages/eslint-config-solid/package.json new file mode 100644 index 0000000..e7c7549 --- /dev/null +++ b/packages/eslint-config-solid/package.json @@ -0,0 +1,77 @@ +{ + "name": "@kurone-kito/eslint-config-solid", + "version": "0.16.1", + "description": "My ESLint configuration for Solid.js projects", + "keywords": [ + "config", + "eslint", + "eslintconfig", + "eslintrc", + "solid-js" + ], + "homepage": "https://github.com/kurone-kito/lints-config#readme", + "bugs": "https://github.com/kurone-kito/lints-config/issues", + "repository": { + "type": "git", + "url": "https://github.com/kurone-kito/lints-config.git", + "directory": "packages/eslint-config-solid" + }, + "license": "MIT", + "author": "kurone-kito (https://kit.black/)", + "type": "module", + "main": "./dist/index.mjs", + "types": "./dist/index.d.mts", + "files": [ + "dist" + ], + "scripts": { + "build": "conc \"yarn:build:*\"", + "build:license": "cpy --flat ../../LICENSE .", + "build:ts": "tsc", + "clean": "rimraf -g \"*.tgz\" \"*.tsbuildinfo\" dist LICENSE", + "prepack": "conc -m 1 \"yarn:clean\" \"yarn:build\"", + "start": "tsc --watch" + }, + "dependencies": { + "@cspell/eslint-plugin": "^8.15.7", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "^9.14.0", + "@kurone-kito/eslint-config-base": "workspace:^", + "@typescript-eslint/eslint-plugin": "^8.13.0", + "@typescript-eslint/parser": "^8.13.0", + "eslint-config-stylelint": "^23.0.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-solid": "^0.14.3", + "eslint-plugin-storybook": "^0.11.0", + "eslint-plugin-tailwindcss": "^3.17.5", + "typescript-eslint": "^8.13.0" + }, + "devDependencies": { + "@kurone-kito/typescript-config": "workspace:^", + "@types/eslint": "^9.6.1", + "@types/eslint-plugin-tailwindcss": "^3.17.0", + "@types/eslint__eslintrc": "^2.1.2", + "@types/eslint__js": "^8.42.3", + "@types/node": "^22.9.0", + "@typescript-eslint/utils": "^8.13.0", + "concurrently": "^9.1.0", + "cpy-cli": "^5.0.0", + "eslint": "^9.14.0", + "rimraf": "^5.0.10", + "typescript": "~5.6.3" + }, + "peerDependencies": { + "eslint": ">=9.x.x" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + }, + "engines": { + "node": "^18.20 || ^20.10 || >=22" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/eslint-config-solid/src/index.mts b/packages/eslint-config-solid/src/index.mts new file mode 100644 index 0000000..f81cd78 --- /dev/null +++ b/packages/eslint-config-solid/src/index.mts @@ -0,0 +1,25 @@ +import baseConfig from '@kurone-kito/eslint-config-base'; +import type { TSESLint } from '@typescript-eslint/utils'; +import solid from 'eslint-plugin-solid/configs/typescript'; +import tailwind from 'eslint-plugin-tailwindcss'; +import tsEslint from 'typescript-eslint'; +import { storybookConfig } from './storybook.mjs'; +import { compat } from './utils.mjs'; + +/** + * The ESLint configuration for the base rules. + * + * @see {@link https://github.com/microsoft/TypeScript/issues/47663} + */ +const config: TSESLint.FlatConfig.ConfigArray = tsEslint.config( + ...([ + ...baseConfig, + solid, + ...storybookConfig, + ...tailwind.configs['flat/recommended'], + ...compat.extends('eslint-config-stylelint'), + { languageOptions: { parserOptions: { ecmaFeatures: { jsx: true } } } }, + ] as tsEslint.ConfigWithExtends[]), +); + +export default config; diff --git a/packages/eslint-config-solid/src/storybook.mts b/packages/eslint-config-solid/src/storybook.mts new file mode 100644 index 0000000..15948c4 --- /dev/null +++ b/packages/eslint-config-solid/src/storybook.mts @@ -0,0 +1,33 @@ +import type { Linter } from 'eslint'; + +/** The configuration for ESLint to Storybook */ +export const storybookConfig: readonly Linter.Config[] = [ + { + files: ['**/*.stories.?([cm])[jt]s?(x)'], + rules: { + /** + * Unconditionally allow export to `default`. + * + * The default is unknown, but since Storybook component definitions + * are structurally dependent on export to `default`, this permission + * is explicitly stated to prevent influence by later configuration + * updates. + */ + 'import/no-anonymous-default-export': 'off', + /** + * Exporting code that depends `on devDependencies is` allowed only + * for specific packages on an exception basis, and it is prohibited + * by default. + * + * To organize dependencies, only packages that directly depend on + * the product code should be listed in the dependencies list, so + * Storybook component definitions not included in the product code + * are exceptionally allowed to rely on `devDependencies`. + */ + 'n/no-unpublished-import': [ + 'error', + { allowModules: ['@storybook/testing-library'] }, + ], + }, + }, +]; diff --git a/packages/eslint-config-solid/src/utils.mts b/packages/eslint-config-solid/src/utils.mts new file mode 100644 index 0000000..5b4d1cb --- /dev/null +++ b/packages/eslint-config-solid/src/utils.mts @@ -0,0 +1,13 @@ +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { FlatCompat } from '@eslint/eslintrc'; +import eslint from '@eslint/js'; + +/** The directory of the current file. */ +export const __dirname = dirname(fileURLToPath(import.meta.url)); + +/** The compatibility layer for ESLint configuration. */ +export const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: eslint.configs.recommended, +}); diff --git a/packages/eslint-config-solid/tsconfig.json b/packages/eslint-config-solid/tsconfig.json new file mode 100644 index 0000000..5b22c98 --- /dev/null +++ b/packages/eslint-config-solid/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "lib": ["ESNext"], + "outDir": "dist", + "rootDir": "src", + "skipLibCheck": true, + "types": ["node"] + }, + "extends": "@kurone-kito/typescript-config/tsconfig.json" +} diff --git a/yarn.lock b/yarn.lock index b727993..837321a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1094,7 +1094,7 @@ __metadata: languageName: unknown linkType: soft -"@kurone-kito/eslint-config-react@workspace:^, @kurone-kito/eslint-config-react@workspace:packages/eslint-config-react": +"@kurone-kito/eslint-config-react@workspace:packages/eslint-config-react": version: 0.0.0-use.local resolution: "@kurone-kito/eslint-config-react@workspace:packages/eslint-config-react" dependencies: @@ -1134,6 +1134,42 @@ __metadata: languageName: unknown linkType: soft +"@kurone-kito/eslint-config-solid@workspace:packages/eslint-config-solid": + version: 0.0.0-use.local + resolution: "@kurone-kito/eslint-config-solid@workspace:packages/eslint-config-solid" + dependencies: + "@cspell/eslint-plugin": "npm:^8.15.7" + "@eslint/eslintrc": "npm:^3.1.0" + "@eslint/js": "npm:^9.14.0" + "@kurone-kito/eslint-config-base": "workspace:^" + "@kurone-kito/typescript-config": "workspace:^" + "@types/eslint": "npm:^9.6.1" + "@types/eslint-plugin-tailwindcss": "npm:^3.17.0" + "@types/eslint__eslintrc": "npm:^2.1.2" + "@types/eslint__js": "npm:^8.42.3" + "@types/node": "npm:^22.9.0" + "@typescript-eslint/eslint-plugin": "npm:^8.13.0" + "@typescript-eslint/parser": "npm:^8.13.0" + "@typescript-eslint/utils": "npm:^8.13.0" + concurrently: "npm:^9.1.0" + cpy-cli: "npm:^5.0.0" + eslint: "npm:^9.14.0" + eslint-config-stylelint: "npm:^23.0.0" + eslint-plugin-import: "npm:^2.31.0" + eslint-plugin-solid: "npm:^0.14.3" + eslint-plugin-storybook: "npm:^0.11.0" + eslint-plugin-tailwindcss: "npm:^3.17.5" + rimraf: "npm:^5.0.10" + typescript: "npm:~5.6.3" + typescript-eslint: "npm:^8.13.0" + peerDependencies: + eslint: ">=9.x.x" + peerDependenciesMeta: + eslint: + optional: true + languageName: unknown + linkType: soft + "@kurone-kito/lint-staged-config@workspace:^, @kurone-kito/lint-staged-config@workspace:packages/lint-staged-config": version: 0.0.0-use.local resolution: "@kurone-kito/lint-staged-config@workspace:packages/lint-staged-config" @@ -1172,7 +1208,6 @@ __metadata: "@kurone-kito/commitlint-config": "workspace:^" "@kurone-kito/cspell-config": "workspace:^" "@kurone-kito/eslint-config-base": "workspace:^" - "@kurone-kito/eslint-config-react": "workspace:^" "@kurone-kito/lint-staged-config": "workspace:^" "@kurone-kito/markdownlint-config": "workspace:^" "@kurone-kito/prettier-config": "workspace:^" @@ -1676,7 +1711,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.13.0, @typescript-eslint/utils@npm:^8.12.2, @typescript-eslint/utils@npm:^8.13.0, @typescript-eslint/utils@npm:^8.8.1": +"@typescript-eslint/utils@npm:8.13.0, @typescript-eslint/utils@npm:^7.13.1 || ^8.0.0, @typescript-eslint/utils@npm:^8.12.2, @typescript-eslint/utils@npm:^8.13.0, @typescript-eslint/utils@npm:^8.8.1": version: 8.13.0 resolution: "@typescript-eslint/utils@npm:8.13.0" dependencies: @@ -3593,6 +3628,22 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-solid@npm:^0.14.3": + version: 0.14.3 + resolution: "eslint-plugin-solid@npm:0.14.3" + dependencies: + "@typescript-eslint/utils": "npm:^7.13.1 || ^8.0.0" + estraverse: "npm:^5.3.0" + is-html: "npm:^2.0.0" + kebab-case: "npm:^1.0.2" + known-css-properties: "npm:^0.30.0" + style-to-object: "npm:^1.0.6" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + checksum: 10/6955aa677a3ff8ef97adc94f5f64e7e58b6a2bd81a624ca083f248d48a26e5511bf66f8961503af3c6d60820bafa7641d28e7c789b985cab753851e92720efc9 + languageName: node + linkType: hard + "eslint-plugin-storybook@npm:^0.11.0": version: 0.11.0 resolution: "eslint-plugin-storybook@npm:0.11.0" @@ -4412,6 +4463,13 @@ __metadata: languageName: node linkType: hard +"html-tags@npm:^3.0.0": + version: 3.3.1 + resolution: "html-tags@npm:3.3.1" + checksum: 10/d0e808544b92d8b999cbcc86d539577255a2f0f2f4f73110d10749d1d36e6fe6ad706a0355a8477afb6e000ecdc93d8455b3602951f9a2b694ac9e28f1b52878 + languageName: node + linkType: hard + "htmlparser2@npm:3.8.x": version: 3.8.3 resolution: "htmlparser2@npm:3.8.3" @@ -4520,6 +4578,13 @@ __metadata: languageName: node linkType: hard +"inline-style-parser@npm:0.2.4": + version: 0.2.4 + resolution: "inline-style-parser@npm:0.2.4" + checksum: 10/80814479d1f3c9cbd102f9de4cd6558cf43cc2e48640e81c4371c3634f1e8b6dfeb2f21063cfa31d46cc83e834c20cd59ed9eeed9bfd45ef5bc02187ad941faf + languageName: node + linkType: hard + "internal-slot@npm:^1.0.7": version: 1.0.7 resolution: "internal-slot@npm:1.0.7" @@ -4676,6 +4741,15 @@ __metadata: languageName: node linkType: hard +"is-html@npm:^2.0.0": + version: 2.0.0 + resolution: "is-html@npm:2.0.0" + dependencies: + html-tags: "npm:^3.0.0" + checksum: 10/0cc233e3851453913023560bcd2411a9294bfa18f994d4428f2692d2cfb7f90e5521a42cd4c6a62bf1bc7d42301cb214de442766cbd12a9aa52398d34ab5a2a7 + languageName: node + linkType: hard + "is-map@npm:^2.0.3": version: 2.0.3 resolution: "is-map@npm:2.0.3" @@ -5004,6 +5078,13 @@ __metadata: languageName: node linkType: hard +"kebab-case@npm:^1.0.2": + version: 1.0.2 + resolution: "kebab-case@npm:1.0.2" + checksum: 10/bf01164e11c544ee9b3aa1a91c2e7d6aa6b3356b834a5e885d43f36db14aae5d347cd4a298a566133321b82fde6bac6b597f148ac19bfd3d3fc81e1034a79729 + languageName: node + linkType: hard + "keyv@npm:^4.0.0, keyv@npm:^4.5.3, keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" @@ -5020,6 +5101,13 @@ __metadata: languageName: node linkType: hard +"known-css-properties@npm:^0.30.0": + version: 0.30.0 + resolution: "known-css-properties@npm:0.30.0" + checksum: 10/baed51f1c6baf0a904d0c5a041ebdc3a33a22af65a8dcdf7c2ecc22f80360ee44d2992737b745ed2e16a74f37cbb668a27d1e469d776286688921d0b8f0d3c04 + languageName: node + linkType: hard + "language-subtag-registry@npm:^0.3.20": version: 0.3.23 resolution: "language-subtag-registry@npm:0.3.23" @@ -7092,6 +7180,15 @@ __metadata: languageName: node linkType: hard +"style-to-object@npm:^1.0.6": + version: 1.0.8 + resolution: "style-to-object@npm:1.0.8" + dependencies: + inline-style-parser: "npm:0.2.4" + checksum: 10/530b067325e3119bfaf75bdbe25cc86b02b559db00d881a74b98a2d5bb10ac953d1b455ed90c825963cf3b4bdaa1bda45f406d78d987391434b8d8ab3835df4e + languageName: node + linkType: hard + "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0"