@yopem/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,22 @@
1
+ # @yopem/eslint-config
2
+
3
+ Yopem ESLint configuration.
4
+
5
+ ## Installation
6
+
7
+ ```sh
8
+ npm install @yopem/eslint-config
9
+ # or
10
+ pnpm add @yopem/eslint-config
11
+ # or
12
+ yarn add @yopem/eslint-config
13
+ # or
14
+ bun add @yopem/eslint-config
15
+ # or
16
+ deno install npm:@yopem/eslint-config
17
+ ```
18
+
19
+ ## Licence
20
+
21
+ This project is licensed under the terms of the
22
+ [MIT license](https://github.com/yopem/tooling/blob/main/LICENSE.md).
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "@yopem/eslint-config",
3
+ "version": "0.1.0",
4
+ "description": "",
5
+ "keywords": [
6
+ "eslint",
7
+ "eslint-config",
8
+ "tooling"
9
+ ],
10
+ "type": "module",
11
+ "main": "src/base.js",
12
+ "module": "src/base.js",
13
+ "types": "src/types.d.ts",
14
+ "files": [
15
+ "src"
16
+ ],
17
+ "exports": {
18
+ "./base": {
19
+ "source": "./src/base.js",
20
+ "import": {
21
+ "types": "./src/types.d.ts",
22
+ "default": "./src/base.js"
23
+ }
24
+ },
25
+ "./nextjs": {
26
+ "source": "./src/nextjs.js",
27
+ "import": {
28
+ "types": "./src/types.d.ts",
29
+ "default": "./src/nextjs.js"
30
+ }
31
+ },
32
+ "./react": {
33
+ "source": "./src/react.js",
34
+ "import": {
35
+ "types": "./src/types.d.ts",
36
+ "default": "./src/react.js"
37
+ }
38
+ },
39
+ "./tailwindcss": {
40
+ "source": "./src/tailwindcss.js",
41
+ "import": {
42
+ "types": "./src/types.d.ts",
43
+ "default": "./src/tailwindcss.js"
44
+ }
45
+ },
46
+ "./package.json": "./package.json"
47
+ },
48
+ "sideEffects": false,
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "author": "Karyana Yandi <karyana@yandi.me>",
53
+ "license": "MIT",
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "https://github.com/yopem/tooling",
57
+ "directory": "packages/tooling/eslint"
58
+ },
59
+ "bugs": {
60
+ "url": "https://github.com/yopem/tooling/issues"
61
+ },
62
+ "scripts": {
63
+ "lint": "eslint ./src",
64
+ "lint:fix": "eslint ./src --fix",
65
+ "typecheck": "tsc --noEmit"
66
+ },
67
+ "dependencies": {
68
+ "@eslint/compat": "1.2.5",
69
+ "@eslint/js": "9.19.0",
70
+ "@next/eslint-plugin-next": "15.1.6",
71
+ "eslint": "9.19.0",
72
+ "eslint-config-prettier": "10.0.1",
73
+ "eslint-plugin-import": "2.31.0",
74
+ "eslint-plugin-jsx-a11y": "6.10.2",
75
+ "eslint-plugin-prettier": "5.2.3",
76
+ "eslint-plugin-react": "7.37.4",
77
+ "eslint-plugin-react-hooks": "5.1.0",
78
+ "eslint-plugin-tailwindcss": "3.18.0",
79
+ "eslint-plugin-turbo": "2.3.4",
80
+ "typescript-eslint": "8.22.0"
81
+ },
82
+ "devDependencies": {
83
+ "@types/eslint__js": "8.42.3",
84
+ "@yopem/prettier-config": "*",
85
+ "@yopem/typescript-config": "*",
86
+ "prettier": "3.4.2",
87
+ "typescript": "5.7.3"
88
+ },
89
+ "prettier": "@yopem/prettier-config/base"
90
+ }
package/src/base.js ADDED
@@ -0,0 +1,108 @@
1
+ /// <reference types="./types.d.ts" />
2
+
3
+ import fs from "fs"
4
+ import path from "node:path"
5
+ import { fileURLToPath } from "node:url"
6
+ import { includeIgnoreFile } from "@eslint/compat"
7
+ import eslint from "@eslint/js"
8
+ import eslintConfigPrettier from "eslint-config-prettier"
9
+ import importPlugin from "eslint-plugin-import"
10
+ import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"
11
+ import turboPlugin from "eslint-plugin-turbo"
12
+ import tseslint from "typescript-eslint"
13
+
14
+ const __filename = fileURLToPath(import.meta.url)
15
+ const __dirname = path.dirname(__filename)
16
+ const gitignorePath = path.resolve(__dirname, ".gitignore")
17
+
18
+ export default tseslint.config(
19
+ fs.existsSync(gitignorePath) && includeIgnoreFile(gitignorePath),
20
+ { ignores: ["**/*.config.*"] },
21
+
22
+ eslintConfigPrettier,
23
+ eslintPluginPrettierRecommended,
24
+ {
25
+ files: ["**/*.js", "**/*.ts", "**/*.tsx"],
26
+ plugins: {
27
+ import: importPlugin,
28
+ turbo: turboPlugin,
29
+ },
30
+ extends: [
31
+ eslint.configs.recommended,
32
+ ...tseslint.configs.recommended,
33
+ ...tseslint.configs.recommendedTypeChecked,
34
+ ...tseslint.configs.stylisticTypeChecked,
35
+ ],
36
+ rules: {
37
+ ...turboPlugin.configs.recommended.rules,
38
+ "@typescript-eslint/no-unused-vars": [
39
+ "error",
40
+ { argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
41
+ ],
42
+ "@typescript-eslint/consistent-type-imports": [
43
+ "warn",
44
+ { prefer: "type-imports", fixStyle: "separate-type-imports" },
45
+ ],
46
+ "@typescript-eslint/no-misused-promises": [
47
+ 2,
48
+ { checksVoidReturn: { attributes: false } },
49
+ ],
50
+ "@typescript-eslint/no-unnecessary-condition": [
51
+ "error",
52
+ {
53
+ allowConstantLoopConditions: true,
54
+ },
55
+ ],
56
+ "@typescript-eslint/ban-ts-comment": "off",
57
+ "@typescript-eslint/no-non-null-assertion": "error",
58
+ "@typescript-eslint/no-unsafe-argument": "off",
59
+ "@typescript-eslint/no-unsafe-assignment": "off",
60
+ "@typescript-eslint/no-unsafe-call": "off",
61
+ "@typescript-eslint/no-unsafe-member-access": "off",
62
+ "@typescript-eslint/unbound-method": "off",
63
+ "import/consistent-type-specifier-style": ["off"],
64
+ "no-restricted-imports": [
65
+ "error",
66
+ {
67
+ patterns: [
68
+ {
69
+ group: ["../"],
70
+ message: `Relative imports are not allowed. Please use '@/' instead.`,
71
+ },
72
+ ],
73
+ },
74
+ ],
75
+ },
76
+ },
77
+ {
78
+ linterOptions: { reportUnusedDisableDirectives: true },
79
+ languageOptions: { parserOptions: { projectService: true } },
80
+ },
81
+ )
82
+
83
+ export const restrictEnvAccess = tseslint.config(
84
+ { ignores: ["**/env.ts"] },
85
+ {
86
+ files: ["**/*.js", "**/*.ts", "**/*.tsx"],
87
+ rules: {
88
+ "no-restricted-properties": [
89
+ "error",
90
+ {
91
+ object: "process",
92
+ property: "env",
93
+ message:
94
+ "Use `import env from '@/env'` instead to ensure validated types.",
95
+ },
96
+ ],
97
+ "no-restricted-imports": [
98
+ "error",
99
+ {
100
+ name: "process",
101
+ importNames: ["env"],
102
+ message:
103
+ "Use `import env from '@/env'` instead to ensure validated types.",
104
+ },
105
+ ],
106
+ },
107
+ },
108
+ )
package/src/nextjs.js ADDED
@@ -0,0 +1,16 @@
1
+ import nextPlugin from "@next/eslint-plugin-next"
2
+
3
+ /** @type {Awaited<import('typescript-eslint').Config>} */
4
+ export default [
5
+ {
6
+ files: ["**/*.ts", "**/*.tsx"],
7
+ plugins: {
8
+ "@next/next": nextPlugin,
9
+ },
10
+ rules: {
11
+ ...nextPlugin.configs.recommended.rules,
12
+ ...nextPlugin.configs["core-web-vitals"].rules,
13
+ "@next/next/no-duplicate-head": "off",
14
+ },
15
+ },
16
+ ]
package/src/react.js ADDED
@@ -0,0 +1,22 @@
1
+ import reactPlugin from "eslint-plugin-react"
2
+ import hooksPlugin from "eslint-plugin-react-hooks"
3
+
4
+ /** @type {Awaited<import('typescript-eslint').Config>} */
5
+ export default [
6
+ {
7
+ files: ["**/*.ts", "**/*.tsx"],
8
+ plugins: {
9
+ react: reactPlugin,
10
+ "react-hooks": hooksPlugin,
11
+ },
12
+ rules: {
13
+ ...reactPlugin.configs["jsx-runtime"].rules,
14
+ ...hooksPlugin.configs.recommended.rules,
15
+ },
16
+ languageOptions: {
17
+ globals: {
18
+ React: "writable",
19
+ },
20
+ },
21
+ },
22
+ ]
@@ -0,0 +1,19 @@
1
+ import tailwindcss from "eslint-plugin-tailwindcss"
2
+
3
+ /** @type {Awaited<import('typescript-eslint').Config>} */
4
+ export default [
5
+ {
6
+ files: ["**/*.ts", "**/*.tsx"],
7
+ plugins: {
8
+ tailwindcss: tailwindcss,
9
+ },
10
+ rules: {
11
+ ...tailwindcss.configs.recommended.rules,
12
+ },
13
+ languageOptions: {
14
+ globals: {
15
+ React: "writable",
16
+ },
17
+ },
18
+ },
19
+ ]
package/src/types.d.ts ADDED
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Since the ecosystem hasn't fully migrated to ESLint's new FlatConfig system yet,
3
+ * we "need" to type some of the plugins manually :(
4
+ */
5
+
6
+ declare module "eslint-plugin-import" {
7
+ import type { Linter, Rule } from "eslint"
8
+
9
+ export const configs: {
10
+ recommended: { rules: Linter.RulesRecord }
11
+ }
12
+ export const rules: Record<string, Rule.RuleModule>
13
+ }
14
+
15
+ declare module "eslint-plugin-react" {
16
+ import type { Linter, Rule } from "eslint"
17
+
18
+ export const configs: {
19
+ recommended: { rules: Linter.RulesRecord }
20
+ all: { rules: Linter.RulesRecord }
21
+ "jsx-runtime": { rules: Linter.RulesRecord }
22
+ }
23
+ export const rules: Record<string, Rule.RuleModule>
24
+ }
25
+
26
+ declare module "eslint-plugin-react-hooks" {
27
+ import type { Linter, Rule } from "eslint"
28
+
29
+ export const configs: {
30
+ recommended: {
31
+ rules: {
32
+ "rules-of-hooks": Linter.RuleEntry
33
+ "exhaustive-deps": Linter.RuleEntry
34
+ }
35
+ }
36
+ }
37
+ export const rules: Record<string, Rule.RuleModule>
38
+ }
39
+
40
+ declare module "eslint-plugin-tailwindcss" {
41
+ import type { Linter, Rule } from "eslint"
42
+
43
+ export const configs: {
44
+ recommended: {
45
+ rules: {
46
+ "classnames-order": Linter.RuleEntry
47
+ "enforces-negative-arbitrary-values": Linter.RuleEntry
48
+ "enforces-shorthand": Linter.RuleEntry
49
+ "migration-from-tailwind-2": Linter.RuleEntry
50
+ "no-arbitrary-value": Linter.RuleEntry
51
+ "no-contradicting-classname": Linter.RuleEntry
52
+ "no-custom-classname": Linter.RuleEntry
53
+ "no-unnecessary-arbitrary-value": Linter.RuleEntry
54
+ }
55
+ }
56
+ }
57
+ export const rules: Record<string, Rule.RuleModule>
58
+ }
59
+
60
+ declare module "@next/eslint-plugin-next" {
61
+ import type { Linter, Rule } from "eslint"
62
+
63
+ export const configs: {
64
+ recommended: { rules: Linter.RulesRecord }
65
+ "core-web-vitals": { rules: Linter.RulesRecord }
66
+ }
67
+ export const rules: Record<string, Rule.RuleModule>
68
+ }