@dcl/eslint-config 2.4.3 → 2.4.4-20934016618.commit-03e6954

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/.eslintrc.js CHANGED
@@ -1,8 +1,14 @@
1
+ const { getTypeScriptProjectParserOptions } = require('./utils/tsconfig')
2
+
3
+ const tsProject = getTypeScriptProjectParserOptions()
4
+ const hasTypeScriptProject = Boolean(tsProject)
5
+
1
6
  module.exports = {
7
+ parser: '@typescript-eslint/parser',
2
8
  parserOptions: {
3
9
  ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features
4
- sourceType: "module", // Allows for the use of imports,
5
- project: []
10
+ sourceType: 'module', // Allows for the use of imports
11
+ ...(tsProject ?? {})
6
12
  },
7
13
  extends: [
8
14
  'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
@@ -23,7 +29,7 @@ module.exports = {
23
29
  "@typescript-eslint/no-inferrable-types": 0,
24
30
  "@typescript-eslint/no-empty-function": "off",
25
31
  "@typescript-eslint/no-explicit-any": "off",
26
- "@typescript-eslint/no-floating-promises": 2,
32
+ "@typescript-eslint/no-floating-promises": hasTypeScriptProject ? 2 : "off",
27
33
  "@typescript-eslint/no-non-null-assertion": "off",
28
34
  "@typescript-eslint/no-unused-vars": [
29
35
  "warn",
package/README.md CHANGED
@@ -1,23 +1,157 @@
1
1
  # DCL ESLint & Prettier Config
2
2
 
3
3
  ## Installation
4
+
4
5
  ```sh
6
+ # Using Yarn
7
+ yarn add -D @dcl/eslint-config
8
+
9
+ # Using npm
5
10
  npm install -D @dcl/eslint-config
6
11
  ```
7
12
 
8
- ## Usage
13
+ ## Prerequisites
14
+
15
+ - **Node.js** >= 18.18.0
16
+ - **ESLint** >= 9.0.0
17
+ - **TypeScript** (for TypeScript-based presets)
18
+
19
+ ## Usage (ESLint 9, `eslint.config.js`)
9
20
 
10
- In `eslintrc.json`:
21
+ In your `eslint.config.js`:
11
22
 
12
23
  ```js
24
+ const coreDapps = require("@dcl/eslint-config/core-dapps.config");
25
+
26
+ module.exports = [...coreDapps];
27
+ ```
28
+
29
+ Other presets available:
30
+
31
+ - `@dcl/eslint-config/core-services.config`
32
+ - `@dcl/eslint-config/dapps.config`
33
+ - `@dcl/eslint-config/ui.config`
34
+ - `@dcl/eslint-config/sdk.config`
35
+
36
+ ## Legacy usage with `.eslintrc` (ESLint 8 / transition)
37
+
38
+ In your `.eslintrc.cjs`:
39
+
40
+ ```js
41
+ module.exports = {
42
+ extends: ["@dcl/eslint-config/core-dapps"],
43
+ };
44
+ ```
45
+
46
+ ## Type-aware rules without manual `parserOptions.project`
47
+
48
+ TypeScript presets (for example `core-dapps`) **auto-detect** a tsconfig in the consumer repo:
49
+
50
+ - `tsconfig.eslint.json` (preferred)
51
+ - `tsconfig.json`
52
+ - `tsconfig.app.json` / `tsconfig.node.json` (Vite)
53
+
54
+ If no tsconfig is found, rules that require type information are disabled to avoid crashes.
55
+
56
+ ## npm-package-json-lint (shareable config)
57
+
58
+ In your `.npmpackagejsonlintrc.json`:
59
+
60
+ ```json
13
61
  {
14
- "extends": "@dcl/eslint-config",
15
- "parserOptions": {
16
- "project": ["tsconfig.json", "test/tsconfig.json"]
17
- }
62
+ "extends": "@dcl/eslint-config/npm-package-json-lint"
18
63
  }
19
64
  ```
20
65
 
66
+ Key rules:
67
+
68
+ - `dependencies` and `devDependencies` must use **exact versions**
69
+ - automatic exception (computed from your `package.json`): internal packages (`@dcl/*`, `decentraland-*`) may use version ranges (`^`)
70
+
71
+ How the exception works:
72
+
73
+ - `@dcl/eslint-config/npm-package-json-lint` is a **JavaScript config module**.
74
+ - When `npmPkgJsonLint` loads it, it reads the consumer repo `package.json` from `process.cwd()` and builds the exception list from the package names found in `dependencies`/`devDependencies` that match `@dcl/*` or `decentraland-*`.
75
+ - That means you don't need to list exceptions manually: if you add `@dcl/schemas` with `^` it will be allowed; if you add `react` with `^` it will be reported.
76
+
77
+ Monorepos: run `npmPkgJsonLint` from the package folder you want to lint (so `process.cwd()` points to the right `package.json`), or override rules locally.
78
+
79
+ ## Peer dependencies
80
+
81
+ This package publishes most tooling as **peerDependencies**. In the consumer repo you'll need (depending on the preset):
82
+
83
+ - `eslint`
84
+ - `@typescript-eslint/parser`, `@typescript-eslint/eslint-plugin`
85
+ - `prettier`, `eslint-plugin-prettier`, `eslint-config-prettier`
86
+ - `eslint-plugin-import`, `eslint-import-resolver-typescript`
87
+ - `eslint-plugin-react` (if you use React presets)
88
+ - `eslint-plugin-autofix`
89
+
90
+ > Note: some presets configure the `babel-module` resolver; if you use it, install `eslint-import-resolver-babel-module` and its peers (`@babel/core`, `babel-plugin-module-resolver`).
91
+
92
+ ## Upgrading from v1 to v2
93
+
94
+ ### Breaking changes
95
+
96
+ - **ESLint 9 required** – The new flat config (`eslint.config.js`) requires ESLint >= 9.0.0
97
+ - **Peer dependencies** – Plugins are now peer dependencies (you install them in your project)
98
+ - **New entrypoints** – Use `*.config.js` for ESLint 9, keep `*` (without `.config`) for legacy `.eslintrc`
99
+ - **Removed presets** – `gatsby` preset has been removed
100
+
101
+ ### Migration steps
102
+
103
+ 1. **Update the package:**
104
+
105
+ ```sh
106
+ # Yarn
107
+ yarn add -D @dcl/eslint-config@^2.0.0
108
+
109
+ # npm
110
+ npm install -D @dcl/eslint-config@^2.0.0
111
+ ```
112
+
113
+ 2. **Install peer dependencies** (if not already present):
114
+
115
+ ```sh
116
+ # Yarn
117
+ yarn add -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin \
118
+ prettier eslint-plugin-prettier eslint-config-prettier \
119
+ eslint-plugin-import eslint-import-resolver-typescript eslint-plugin-autofix
120
+
121
+ # npm
122
+ npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin \
123
+ prettier eslint-plugin-prettier eslint-config-prettier \
124
+ eslint-plugin-import eslint-import-resolver-typescript eslint-plugin-autofix
125
+ ```
126
+
127
+ 3. **Update your ESLint config:**
128
+
129
+ ```js
130
+ // eslint.config.js (ESLint 9)
131
+ const coreDapps = require("@dcl/eslint-config/core-dapps.config");
132
+
133
+ module.exports = [...coreDapps];
134
+ ```
135
+
136
+ 4. **If you encounter peer dependency conflicts:**
137
+
138
+ ```sh
139
+ # Yarn - Remove conflicting old versions first
140
+ yarn remove eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
141
+
142
+ # Then reinstall with exact versions
143
+ yarn add -D eslint@9.39.2 @typescript-eslint/parser@8.52.0 @typescript-eslint/eslint-plugin@8.52.0
144
+ ```
145
+
146
+ ```sh
147
+ # npm - Remove conflicting old versions first
148
+ npm uninstall eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
149
+
150
+ # Then reinstall with exact versions
151
+ npm install -D eslint@9.39.2 @typescript-eslint/parser@8.52.0 @typescript-eslint/eslint-plugin@8.52.0
152
+ ```
153
+
154
+ > **Note:** Avoid using `--legacy-peer-deps` unless absolutely necessary, as it can mask version incompatibilities.
21
155
 
22
156
  ## License
23
157
 
@@ -0,0 +1,12 @@
1
+ const js = require('@eslint/js')
2
+ const { FlatCompat } = require('@eslint/eslintrc')
3
+
4
+ const compat = new FlatCompat({
5
+ baseDirectory: __dirname,
6
+ recommendedConfig: js.configs.recommended,
7
+ allConfig: js.configs.all
8
+ })
9
+
10
+ module.exports = [...compat.config(require('./core-dapps'))]
11
+
12
+
package/core-dapps.js CHANGED
@@ -1,3 +1,8 @@
1
+ const { getTypeScriptProjectParserOptions } = require("./utils/tsconfig")
2
+
3
+ const tsProject = getTypeScriptProjectParserOptions()
4
+ const hasTypeScriptProject = Boolean(tsProject)
5
+
1
6
  module.exports = {
2
7
  root: true,
3
8
  env: {
@@ -8,6 +13,7 @@ module.exports = {
8
13
  parserOptions: {
9
14
  ecmaVersion: 2018,
10
15
  sourceType: "module",
16
+ ...(tsProject ?? {}),
11
17
  },
12
18
  plugins: ["@typescript-eslint", "react", "prettier", "import", "autofix"],
13
19
  extends: [
@@ -26,73 +32,73 @@ module.exports = {
26
32
  "import/group-exports": "error",
27
33
  "import/exports-last": "error",
28
34
  "@typescript-eslint/no-explicit-any": "error",
29
- "@typescript-eslint/ban-types": "error",
30
35
  "@typescript-eslint/ban-tslint-comment": "error",
31
- "@typescript-eslint/quotes": ["error", "single", { avoidEscape: true }],
36
+ "quotes": ["error", "single", { avoidEscape: true }],
32
37
  "@typescript-eslint/no-misused-promises": [
33
- "error",
34
- { checksVoidReturn: false },
38
+ ...(hasTypeScriptProject ? ["error", { checksVoidReturn: false }] : ["off"]),
35
39
  ],
36
- "@typescript-eslint/no-unnecessary-type-assertion": "error",
40
+ "@typescript-eslint/no-unnecessary-type-assertion": hasTypeScriptProject ? "error" : "off",
37
41
  "@typescript-eslint/no-unused-vars": [
38
42
  "error",
39
43
  { argsIgnorePattern: "^_", ignoreRestSiblings: true },
40
44
  ],
41
- "@typescript-eslint/unbound-method": "error",
42
- "@typescript-eslint/naming-convention": [
43
- "error",
44
- { selector: "default", format: ["camelCase"] },
45
- { selector: "variableLike", format: ["camelCase"] },
46
- {
47
- selector: "variable",
48
- format: ["camelCase", "UPPER_CASE"],
49
- leadingUnderscore: "allow",
50
- },
51
- {
52
- selector: "variable",
53
- types: ["function"],
54
- format: ["PascalCase", "camelCase"],
55
- },
56
- {
57
- selector: "parameter",
58
- format: ["camelCase"],
59
- leadingUnderscore: "allow",
60
- },
61
- { selector: "memberLike", format: ["camelCase"] },
62
- {
63
- selector: "memberLike",
64
- modifiers: ["private"],
65
- format: ["camelCase"],
66
- leadingUnderscore: "allow",
67
- },
68
- { selector: "typeLike", format: ["PascalCase"] },
69
- { selector: "typeParameter", format: ["PascalCase"], prefix: ["T"] },
70
- {
71
- selector: "interface",
72
- format: ["PascalCase"],
73
- custom: { regex: "^I[A-Z]", match: false },
74
- },
75
- {
76
- selector: [
77
- "variable",
78
- "function",
79
- "objectLiteralProperty",
80
- "objectLiteralMethod",
81
- ],
82
- types: ["function"],
83
- format: ["StrictPascalCase", "strictCamelCase"],
84
- },
85
- {
86
- selector: ["enum"],
87
- format: ["UPPER_CASE", "PascalCase"],
88
- leadingUnderscore: "allow",
89
- },
90
- {
91
- selector: ["enumMember"],
92
- format: ["UPPER_CASE"],
93
- leadingUnderscore: "allow",
94
- },
95
- ],
45
+ "@typescript-eslint/unbound-method": hasTypeScriptProject ? "error" : "off",
46
+ "@typescript-eslint/naming-convention": hasTypeScriptProject
47
+ ? [
48
+ "error",
49
+ { selector: "default", format: ["camelCase"] },
50
+ { selector: "variableLike", format: ["camelCase"] },
51
+ {
52
+ selector: "variable",
53
+ format: ["camelCase", "UPPER_CASE"],
54
+ leadingUnderscore: "allow",
55
+ },
56
+ {
57
+ selector: "variable",
58
+ types: ["function"],
59
+ format: ["PascalCase", "camelCase"],
60
+ },
61
+ {
62
+ selector: "parameter",
63
+ format: ["camelCase"],
64
+ leadingUnderscore: "allow",
65
+ },
66
+ { selector: "memberLike", format: ["camelCase"] },
67
+ {
68
+ selector: "memberLike",
69
+ modifiers: ["private"],
70
+ format: ["camelCase"],
71
+ leadingUnderscore: "allow",
72
+ },
73
+ { selector: "typeLike", format: ["PascalCase"] },
74
+ { selector: "typeParameter", format: ["PascalCase"], prefix: ["T"] },
75
+ {
76
+ selector: "interface",
77
+ format: ["PascalCase"],
78
+ custom: { regex: "^I[A-Z]", match: false },
79
+ },
80
+ {
81
+ selector: [
82
+ "variable",
83
+ "function",
84
+ "objectLiteralProperty",
85
+ "objectLiteralMethod",
86
+ ],
87
+ types: ["function"],
88
+ format: ["StrictPascalCase", "strictCamelCase"],
89
+ },
90
+ {
91
+ selector: ["enum"],
92
+ format: ["UPPER_CASE", "PascalCase"],
93
+ leadingUnderscore: "allow",
94
+ },
95
+ {
96
+ selector: ["enumMember"],
97
+ format: ["UPPER_CASE"],
98
+ leadingUnderscore: "allow",
99
+ },
100
+ ]
101
+ : "off",
96
102
  "@typescript-eslint/no-empty-function": "off",
97
103
  "@typescript-eslint/explicit-module-boundary-types": "off",
98
104
  "@typescript-eslint/no-non-null-assertion": "off",
@@ -0,0 +1,12 @@
1
+ const js = require('@eslint/js')
2
+ const { FlatCompat } = require('@eslint/eslintrc')
3
+
4
+ const compat = new FlatCompat({
5
+ baseDirectory: __dirname,
6
+ recommendedConfig: js.configs.recommended,
7
+ allConfig: js.configs.all
8
+ })
9
+
10
+ module.exports = [...compat.config(require('./core-services'))]
11
+
12
+
package/core-services.js CHANGED
@@ -1,8 +1,14 @@
1
+ const { getTypeScriptProjectParserOptions } = require("./utils/tsconfig")
2
+
3
+ const tsProject = getTypeScriptProjectParserOptions()
4
+ const hasTypeScriptProject = Boolean(tsProject)
5
+
1
6
  module.exports = {
2
7
  parser: "@typescript-eslint/parser",
3
8
  parserOptions: {
4
9
  ecmaVersion: 2018,
5
10
  sourceType: "module",
11
+ ...(tsProject ?? {}),
6
12
  },
7
13
  env: {
8
14
  node: true,
@@ -26,7 +32,7 @@ module.exports = {
26
32
  "@typescript-eslint/no-inferrable-types": "error",
27
33
  "@typescript-eslint/no-empty-function": "error",
28
34
  "@typescript-eslint/no-explicit-any": "error",
29
- "@typescript-eslint/no-floating-promises": "error",
35
+ "@typescript-eslint/no-floating-promises": hasTypeScriptProject ? "error" : "off",
30
36
  "@typescript-eslint/no-non-null-assertion": "error",
31
37
  "@typescript-eslint/no-namespace": "error",
32
38
  "@typescript-eslint/prefer-optional-chain": "error",
@@ -43,17 +49,6 @@ module.exports = {
43
49
  }
44
50
  ],
45
51
  "import/no-named-as-default-member": "off",
46
- "@typescript-eslint/ban-types": [
47
- "error",
48
- {
49
- types: {
50
- "{}": {
51
- message: "Use Record<string, unknown> instead of {}",
52
- fixWith: "Record<string, unknown>",
53
- },
54
- },
55
- },
56
- ],
57
52
  "@typescript-eslint/explicit-module-boundary-types": "warn",
58
53
  "no-restricted-imports": "off",
59
54
  "@typescript-eslint/no-restricted-imports": "off",
@@ -0,0 +1,12 @@
1
+ const js = require('@eslint/js')
2
+ const { FlatCompat } = require('@eslint/eslintrc')
3
+
4
+ const compat = new FlatCompat({
5
+ baseDirectory: __dirname,
6
+ recommendedConfig: js.configs.recommended,
7
+ allConfig: js.configs.all
8
+ })
9
+
10
+ module.exports = [...compat.config(require('./dapps'))]
11
+
12
+
package/dapps.js CHANGED
@@ -1,3 +1,8 @@
1
+ const { getTypeScriptProjectParserOptions } = require("./utils/tsconfig")
2
+
3
+ const tsProject = getTypeScriptProjectParserOptions()
4
+ const hasTypeScriptProject = Boolean(tsProject)
5
+
1
6
  module.exports = {
2
7
  root: true,
3
8
  env: {
@@ -8,6 +13,7 @@ module.exports = {
8
13
  parserOptions: {
9
14
  ecmaVersion: 2018,
10
15
  sourceType: "module",
16
+ ...(tsProject ?? {}),
11
17
  },
12
18
  plugins: ["@typescript-eslint", "import", "autofix"],
13
19
  extends: [
@@ -24,73 +30,73 @@ module.exports = {
24
30
  "import/group-exports": "error",
25
31
  "import/exports-last": "error",
26
32
  "@typescript-eslint/no-explicit-any": "error",
27
- "@typescript-eslint/ban-types": "error",
28
33
  "@typescript-eslint/ban-tslint-comment": "error",
29
- "@typescript-eslint/quotes": ["error", "single", { avoidEscape: true }],
34
+ "quotes": ["error", "single", { avoidEscape: true }],
30
35
  "@typescript-eslint/no-misused-promises": [
31
- "error",
32
- { checksVoidReturn: false },
36
+ ...(hasTypeScriptProject ? ["error", { checksVoidReturn: false }] : ["off"]),
33
37
  ],
34
- "@typescript-eslint/no-unnecessary-type-assertion": "error",
38
+ "@typescript-eslint/no-unnecessary-type-assertion": hasTypeScriptProject ? "error" : "off",
35
39
  "@typescript-eslint/no-unused-vars": [
36
40
  "error",
37
41
  { argsIgnorePattern: "^_", ignoreRestSiblings: true },
38
42
  ],
39
- "@typescript-eslint/unbound-method": "error",
40
- "@typescript-eslint/naming-convention": [
41
- "error",
42
- { selector: "default", format: ["camelCase"] },
43
- { selector: "variableLike", format: ["camelCase"] },
44
- {
45
- selector: "variable",
46
- format: ["camelCase", "UPPER_CASE"],
47
- leadingUnderscore: "allow",
48
- },
49
- {
50
- selector: "variable",
51
- types: ["function"],
52
- format: ["PascalCase", "camelCase"],
53
- },
54
- {
55
- selector: "parameter",
56
- format: ["camelCase"],
57
- leadingUnderscore: "allow",
58
- },
59
- { selector: "memberLike", format: ["camelCase"] },
60
- {
61
- selector: "memberLike",
62
- modifiers: ["private"],
63
- format: ["camelCase"],
64
- leadingUnderscore: "allow",
65
- },
66
- { selector: "typeLike", format: ["PascalCase"] },
67
- { selector: "typeParameter", format: ["PascalCase"], prefix: ["T"] },
68
- {
69
- selector: "interface",
70
- format: ["PascalCase"],
71
- custom: { regex: "^I[A-Z]", match: false },
72
- },
73
- {
74
- selector: [
75
- "variable",
76
- "function",
77
- "objectLiteralProperty",
78
- "objectLiteralMethod",
79
- ],
80
- types: ["function"],
81
- format: ["StrictPascalCase", "strictCamelCase"],
82
- },
83
- {
84
- selector: ["enum"],
85
- format: ["UPPER_CASE", "PascalCase"],
86
- leadingUnderscore: "allow",
87
- },
88
- {
89
- selector: ["enumMember"],
90
- format: ["UPPER_CASE"],
91
- leadingUnderscore: "allow",
92
- },
93
- ],
43
+ "@typescript-eslint/unbound-method": hasTypeScriptProject ? "error" : "off",
44
+ "@typescript-eslint/naming-convention": hasTypeScriptProject
45
+ ? [
46
+ "error",
47
+ { selector: "default", format: ["camelCase"] },
48
+ { selector: "variableLike", format: ["camelCase"] },
49
+ {
50
+ selector: "variable",
51
+ format: ["camelCase", "UPPER_CASE"],
52
+ leadingUnderscore: "allow",
53
+ },
54
+ {
55
+ selector: "variable",
56
+ types: ["function"],
57
+ format: ["PascalCase", "camelCase"],
58
+ },
59
+ {
60
+ selector: "parameter",
61
+ format: ["camelCase"],
62
+ leadingUnderscore: "allow",
63
+ },
64
+ { selector: "memberLike", format: ["camelCase"] },
65
+ {
66
+ selector: "memberLike",
67
+ modifiers: ["private"],
68
+ format: ["camelCase"],
69
+ leadingUnderscore: "allow",
70
+ },
71
+ { selector: "typeLike", format: ["PascalCase"] },
72
+ { selector: "typeParameter", format: ["PascalCase"], prefix: ["T"] },
73
+ {
74
+ selector: "interface",
75
+ format: ["PascalCase"],
76
+ custom: { regex: "^I[A-Z]", match: false },
77
+ },
78
+ {
79
+ selector: [
80
+ "variable",
81
+ "function",
82
+ "objectLiteralProperty",
83
+ "objectLiteralMethod",
84
+ ],
85
+ types: ["function"],
86
+ format: ["StrictPascalCase", "strictCamelCase"],
87
+ },
88
+ {
89
+ selector: ["enum"],
90
+ format: ["UPPER_CASE", "PascalCase"],
91
+ leadingUnderscore: "allow",
92
+ },
93
+ {
94
+ selector: ["enumMember"],
95
+ format: ["UPPER_CASE"],
96
+ leadingUnderscore: "allow",
97
+ },
98
+ ]
99
+ : "off",
94
100
  "autofix/no-debugger": "error",
95
101
  "sort-imports": [
96
102
  "error",
@@ -0,0 +1,73 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+
4
+ function safeReadJson(filePath) {
5
+ try {
6
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'))
7
+ } catch {
8
+ return null
9
+ }
10
+ }
11
+
12
+ function getInternalPackageExceptions(pkgJsonSection) {
13
+ if (!pkgJsonSection || typeof pkgJsonSection !== 'object') return []
14
+
15
+ return Object.keys(pkgJsonSection).filter(
16
+ name => name.startsWith('@dcl/') || name.startsWith('decentraland-')
17
+ )
18
+ }
19
+
20
+ function getPreferAbsoluteRule(severity, exceptions) {
21
+ return exceptions.length > 0 ? [severity, { exceptions }] : severity
22
+ }
23
+
24
+ const pkgJson = safeReadJson(path.join(process.cwd(), 'package.json'))
25
+
26
+ module.exports = {
27
+ rules: {
28
+ // Dependency Management Standard:
29
+ // - deps/devDeps must be exact
30
+ // - exception: internal Decentraland packages may use ranges (^)
31
+ 'prefer-absolute-version-dependencies': getPreferAbsoluteRule(
32
+ 'warning',
33
+ getInternalPackageExceptions(pkgJson?.dependencies)
34
+ ),
35
+ 'prefer-absolute-version-devDependencies': getPreferAbsoluteRule(
36
+ 'warning',
37
+ getInternalPackageExceptions(pkgJson?.devDependencies)
38
+ ),
39
+ 'no-file-dependencies': 'error',
40
+ 'no-git-dependencies': 'error',
41
+ 'no-duplicate-properties': 'error',
42
+ 'prefer-property-order': [
43
+ 'error',
44
+ [
45
+ 'name',
46
+ 'version',
47
+ 'description',
48
+ 'main',
49
+ 'module',
50
+ 'types',
51
+ 'type',
52
+ 'exports',
53
+ 'files',
54
+ 'scripts',
55
+ 'dependencies',
56
+ 'peerDependencies',
57
+ 'peerDependenciesMeta',
58
+ 'devDependencies',
59
+ 'repository',
60
+ 'keywords',
61
+ 'author',
62
+ 'license',
63
+ 'bugs',
64
+ 'homepage',
65
+ 'engines',
66
+ 'overrides',
67
+ 'publishConfig'
68
+ ]
69
+ ]
70
+ }
71
+ }
72
+
73
+
package/package.json CHANGED
@@ -1,13 +1,76 @@
1
1
  {
2
2
  "name": "@dcl/eslint-config",
3
- "version": "2.4.3",
3
+ "version": "2.4.4-20934016618.commit-03e6954",
4
4
  "description": "Decentraland ESLint config",
5
5
  "main": "index.js",
6
+ "files": [
7
+ "index.js",
8
+ "prettier.js",
9
+ ".eslintrc.js",
10
+ "README.md",
11
+ "LICENSE",
12
+ "sdk.js",
13
+ "sdk.config.js",
14
+ "dapps.js",
15
+ "dapps.config.js",
16
+ "ui.js",
17
+ "ui.config.js",
18
+ "core-services.js",
19
+ "core-services.config.js",
20
+ "core-dapps.js",
21
+ "core-dapps.config.js",
22
+ "npm-package-json-lint.js",
23
+ "utils"
24
+ ],
6
25
  "scripts": {
7
26
  "build": "echo 'done building'",
8
27
  "lint:check": "echo 'done linting'",
9
28
  "test": "jest",
10
- "lint": "eslint -c test/.eslintrc.js test/"
29
+ "lint": "eslint test/"
30
+ },
31
+ "dependencies": {
32
+ "@eslint/eslintrc": "3.3.3",
33
+ "@eslint/js": "9.39.2"
34
+ },
35
+ "peerDependencies": {
36
+ "@typescript-eslint/eslint-plugin": "^8.52.0",
37
+ "@typescript-eslint/parser": "^8.52.0",
38
+ "eslint": "^9.0.0",
39
+ "eslint-config-prettier": "^10.1.8",
40
+ "eslint-import-resolver-babel-module": "^5.3.2",
41
+ "eslint-import-resolver-typescript": "^4.4.4",
42
+ "eslint-plugin-autofix": "^2.2.0",
43
+ "eslint-plugin-import": "^2.32.0",
44
+ "eslint-plugin-prettier": "^5.5.4",
45
+ "eslint-plugin-react": "^7.37.5",
46
+ "prettier": "^3.0.0"
47
+ },
48
+ "peerDependenciesMeta": {
49
+ "eslint-import-resolver-babel-module": {
50
+ "optional": true
51
+ },
52
+ "eslint-plugin-react": {
53
+ "optional": true
54
+ }
55
+ },
56
+ "devDependencies": {
57
+ "@types/jest": "30.0.0",
58
+ "@typescript-eslint/eslint-plugin": "8.52.0",
59
+ "@typescript-eslint/parser": "8.52.0",
60
+ "eslint": "9.39.2",
61
+ "eslint-config-prettier": "10.1.8",
62
+ "eslint-import-resolver-babel-module": "5.3.2",
63
+ "eslint-import-resolver-typescript": "4.4.4",
64
+ "eslint-plugin-autofix": "2.2.0",
65
+ "eslint-plugin-import": "2.32.0",
66
+ "eslint-plugin-prettier": "5.5.4",
67
+ "eslint-plugin-react": "7.37.5",
68
+ "jest": "30.2.0",
69
+ "npm-package-json-lint": "9.1.0",
70
+ "prettier": "3.7.4",
71
+ "react": "19.2.3",
72
+ "ts-jest": "29.4.6",
73
+ "typescript": "5.9.3"
11
74
  },
12
75
  "repository": {
13
76
  "type": "git",
@@ -27,37 +90,8 @@
27
90
  "url": "https://github.com/decentraland/eslint-config/issues"
28
91
  },
29
92
  "homepage": "https://github.com/decentraland/eslint-config#readme",
30
- "dependencies": {
31
- "@typescript-eslint/eslint-plugin": "^6.21.0",
32
- "@typescript-eslint/parser": "^6.21.0",
33
- "eslint": "^8.57.0",
34
- "eslint-config-prettier": "^9.1.0",
35
- "eslint-import-resolver-babel-module": "^5.3.2",
36
- "eslint-import-resolver-typescript": "^3.6.1",
37
- "eslint-plugin-autofix": "^1.1.0",
38
- "eslint-plugin-css-import-order": "^1.1.0",
39
- "eslint-plugin-import": "npm:eslint-plugin-i@^2.29.1",
40
- "eslint-plugin-prettier": "^5.1.3",
41
- "prettier": "^3.3.2"
42
- },
43
- "devDependencies": {
44
- "@types/jest": "^30.0.0",
45
- "jest": "^30.1.3",
46
- "ts-jest": "^29.1.0",
47
- "typescript": "^5.4.5"
93
+ "engines": {
94
+ "node": ">=18.18.0"
48
95
  },
49
- "files": [
50
- "index.js",
51
- "prettier.js",
52
- ".eslintrc.js",
53
- "README.md",
54
- "LICENSE",
55
- "sdk.js",
56
- "gatsby.js",
57
- "dapps.js",
58
- "ui.js",
59
- "core-services.js",
60
- "core-dapps.js"
61
- ],
62
- "commit": "916f0f4c258d88881f80b0eab68cdf06877c337b"
96
+ "commit": "03e69545b9d6a9d3c329f3d6302bd32795bdd47f"
63
97
  }
package/prettier.js CHANGED
@@ -3,7 +3,8 @@ const eslintrc = require("./.eslintrc")
3
3
  module.exports = {
4
4
  parserOptions: eslintrc.parserOptions,
5
5
  rules: {
6
- "@typescript-eslint/no-floating-promises": 2,
6
+ "@typescript-eslint/no-floating-promises":
7
+ eslintrc.rules["@typescript-eslint/no-floating-promises"] === "off" ? "off" : 2,
7
8
  "prettier/prettier": eslintrc.rules["prettier/prettier"],
8
9
  },
9
10
  }
package/sdk.config.js ADDED
@@ -0,0 +1,12 @@
1
+ const js = require('@eslint/js')
2
+ const { FlatCompat } = require('@eslint/eslintrc')
3
+
4
+ const compat = new FlatCompat({
5
+ baseDirectory: __dirname,
6
+ recommendedConfig: js.configs.recommended,
7
+ allConfig: js.configs.all
8
+ })
9
+
10
+ module.exports = [...compat.config(require('./sdk'))]
11
+
12
+
package/sdk.js CHANGED
@@ -1,3 +1,7 @@
1
+ const { hasTypeScriptProject } = require("./utils/tsconfig")
2
+
3
+ const hasTypeScriptConfig = hasTypeScriptProject()
4
+
1
5
  module.exports = {
2
6
  extends: [
3
7
  './.eslintrc.js'
@@ -7,7 +11,7 @@ module.exports = {
7
11
  "@typescript-eslint/no-inferrable-types": 0,
8
12
  "@typescript-eslint/no-empty-function": "off",
9
13
  "@typescript-eslint/no-explicit-any": "off",
10
- "@typescript-eslint/no-floating-promises": 2,
14
+ "@typescript-eslint/no-floating-promises": hasTypeScriptConfig ? 2 : "off",
11
15
  "@typescript-eslint/no-non-null-assertion": "off",
12
16
  "@typescript-eslint/no-namespace": "off",
13
17
  "@typescript-eslint/no-unused-vars": [
package/ui.config.js ADDED
@@ -0,0 +1,12 @@
1
+ const js = require('@eslint/js')
2
+ const { FlatCompat } = require('@eslint/eslintrc')
3
+
4
+ const compat = new FlatCompat({
5
+ baseDirectory: __dirname,
6
+ recommendedConfig: js.configs.recommended,
7
+ allConfig: js.configs.all
8
+ })
9
+
10
+ module.exports = [...compat.config(require('./ui'))]
11
+
12
+
package/ui.js CHANGED
@@ -25,13 +25,9 @@ module.exports = {
25
25
  "import/group-exports": "error",
26
26
  "import/exports-last": "error",
27
27
  "@typescript-eslint/no-explicit-any": "error",
28
- "@typescript-eslint/ban-types": [
28
+ "@typescript-eslint/no-empty-object-type": [
29
29
  "error",
30
- {
31
- types: {
32
- "{}": false,
33
- },
34
- },
30
+ { allowObjectTypes: "always" },
35
31
  ],
36
32
  "@typescript-eslint/no-empty-function": "off",
37
33
  "@typescript-eslint/explicit-module-boundary-types": "off",
@@ -0,0 +1,50 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+
4
+ function fileExists(filePath) {
5
+ try {
6
+ return fs.statSync(filePath).isFile()
7
+ } catch {
8
+ return false
9
+ }
10
+ }
11
+
12
+ /**
13
+ * Returns TypeScript parserOptions for type-aware rules, based on common tsconfig
14
+ * conventions in Decentraland repos.
15
+ *
16
+ * Priority:
17
+ * - tsconfig.eslint.json
18
+ * - tsconfig.json
19
+ * - tsconfig.app.json / tsconfig.node.json (Vite)
20
+ */
21
+ function getTypeScriptProjectParserOptions(cwd = process.cwd()) {
22
+ const eslintTsconfig = 'tsconfig.eslint.json'
23
+ if (fileExists(path.join(cwd, eslintTsconfig))) {
24
+ return { tsconfigRootDir: cwd, project: [eslintTsconfig] }
25
+ }
26
+
27
+ const tsconfig = 'tsconfig.json'
28
+ if (fileExists(path.join(cwd, tsconfig))) {
29
+ return { tsconfigRootDir: cwd, project: [tsconfig] }
30
+ }
31
+
32
+ const viteProjects = ['tsconfig.app.json', 'tsconfig.node.json']
33
+ const found = viteProjects.filter(p => fileExists(path.join(cwd, p)))
34
+ if (found.length > 0) {
35
+ return { tsconfigRootDir: cwd, project: found }
36
+ }
37
+
38
+ return null
39
+ }
40
+
41
+ function hasTypeScriptProject(cwd = process.cwd()) {
42
+ return Boolean(getTypeScriptProjectParserOptions(cwd))
43
+ }
44
+
45
+ module.exports = {
46
+ getTypeScriptProjectParserOptions,
47
+ hasTypeScriptProject
48
+ }
49
+
50
+
package/gatsby.js DELETED
@@ -1,127 +0,0 @@
1
- module.exports = {
2
- parser: "@typescript-eslint/parser",
3
- parserOptions: {
4
- ecmaVersion: 2018,
5
- sourceType: "module",
6
- },
7
- env: {
8
- node: true,
9
- es6: true,
10
- },
11
- plugins: [
12
- "@typescript-eslint",
13
- // TODO: add react
14
- // 'react',
15
- "prettier",
16
- "import",
17
- "autofix",
18
- "css-import-order",
19
- ],
20
- extends: [
21
- "eslint:recommended",
22
- "plugin:@typescript-eslint/recommended",
23
- // TODO: adding react we will need to add the next line
24
- // 'plugin:react/recommended',
25
- "plugin:prettier/recommended",
26
- "plugin:import/recommended",
27
- "plugin:import/typescript",
28
- "plugin:css-import-order/recommended",
29
- ],
30
- rules: {
31
- "import/no-named-as-default-member": "off", // This rule goes
32
- "@typescript-eslint/no-explicit-any": "off",
33
- "@typescript-eslint/ban-types": [
34
- "error",
35
- {
36
- types: {
37
- "{}": false,
38
- },
39
- },
40
- ],
41
- "@typescript-eslint/no-empty-function": "off",
42
- "@typescript-eslint/explicit-module-boundary-types": "off",
43
- "@typescript-eslint/no-non-null-assertion": "off",
44
- "no-restricted-imports": "off",
45
- "@typescript-eslint/no-restricted-imports": [
46
- "error",
47
- {
48
- paths: [
49
- "lodash",
50
- "decentraland-ui",
51
- "decentraland-dapps",
52
- "decentraland-connect",
53
- "decentraland-gatsby",
54
- "semantic-ui-react",
55
- "@dcl/schemas",
56
- ],
57
- patterns: ["lodash.*"],
58
- },
59
- ],
60
-
61
- "autofix/no-debugger": "error",
62
- "sort-imports": [
63
- "error",
64
- {
65
- ignoreDeclarationSort: true, // don't want to sort import lines, use eslint-plugin-import instead
66
- memberSyntaxSortOrder: ["none", "all", "multiple", "single"],
67
- allowSeparatedGroups: true,
68
- },
69
- ],
70
- "import/order": [
71
- "error",
72
- {
73
- groups: [
74
- "builtin",
75
- "external",
76
- "internal",
77
- ["sibling", "parent"], // <- Relative imports, the sibling and parent types they can be mingled together
78
- "index",
79
- "object",
80
- "type",
81
- "unknown",
82
- ],
83
- pathGroupsExcludedImportTypes: ["react", "gatsby", "react-*"],
84
- pathGroups: [
85
- {
86
- pattern: "react",
87
- group: "builtin",
88
- position: "before",
89
- },
90
- {
91
- pattern: "react-*",
92
- group: "builtin",
93
- },
94
- {
95
- pattern: "gatsby",
96
- group: "builtin",
97
- },
98
- {
99
- pattern: "decentraland-*",
100
- group: "internal",
101
- },
102
- {
103
- pattern: "semantic-ui-react",
104
- group: "internal",
105
- },
106
- ],
107
- "newlines-between": "always",
108
- alphabetize: {
109
- order: "asc",
110
- caseInsensitive: true,
111
- },
112
- },
113
- ],
114
- },
115
- settings: {
116
- "import/parsers": {
117
- "@typescript-eslint/parser": [".ts", ".tsx"],
118
- },
119
- "import/resolver": {
120
- typescript: {
121
- alwaysTryTypes: true,
122
- },
123
- node: {},
124
- "babel-module": {},
125
- },
126
- },
127
- };