@pumpn/eslint-config 13.2.0 → 14.0.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/import-map.json CHANGED
@@ -1,13 +1,17 @@
1
1
  {
2
2
  "imports": {
3
3
  "@eslint-community/eslint-plugin-eslint-comments": "npm:@eslint-community/eslint-plugin-eslint-comments@^4.3.0",
4
+ "@eslint-react/eslint-plugin": "npm:@eslint-react/eslint-plugin@^1.5.28",
5
+ "@std/path": "jsr:@std/path",
4
6
  "@stylistic/eslint-plugin": "npm:@stylistic/eslint-plugin@^2.3.0",
7
+ "@typescript-eslint/parser": "npm:@typescript-eslint/parser@^8.0.0-alpha.47",
8
+ "eslint-plugin-depend": "npm:eslint-plugin-depend@^0.9.0",
5
9
  "eslint-plugin-import-x": "npm:eslint-plugin-import-x@^3.0.1",
6
- "eslint-plugin-jsdoc": "npm:eslint-plugin-jsdoc@^48.7.0",
10
+ "eslint-plugin-jsdoc": "npm:eslint-plugin-jsdoc@^48.8.3",
7
11
  "eslint-plugin-no-secrets": "npm:eslint-plugin-no-secrets@^1.0.2",
8
12
  "eslint-plugin-perfectionist": "npm:eslint-plugin-perfectionist@^2.11.0",
9
- "eslint-plugin-promise": "npm:eslint-plugin-promise@^6.4.0",
10
- "eslint-plugin-react": "./patches/eslint-plugin-react/index.js",
13
+ "eslint-plugin-promise": "npm:eslint-plugin-promise@^6.5.1",
14
+ "eslint-plugin-react": "npm:eslint-plugin-react@^7.35.0",
11
15
  "eslint-plugin-redos": "npm:eslint-plugin-redos@^4.4.5",
12
16
  "eslint-plugin-regexp": "npm:eslint-plugin-regexp@^2.6.0",
13
17
  "eslint-plugin-security": "npm:eslint-plugin-security@^3.0.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pumpn/eslint-config",
3
- "version": "13.2.0",
3
+ "version": "14.0.0",
4
4
  "description": "standard eslint config for pumpn code projects",
5
5
  "main": "config.js",
6
6
  "author": "Nano Miratus <nanomiratus@gmail.com>",
@@ -17,19 +17,19 @@
17
17
  "test": "echo 'no tests yet'"
18
18
  },
19
19
  "devDependencies": {
20
- "eslint": "^9.7.0",
21
- "funbridge-jsdoc-template": "github:52-entertainment/funbridge-react-jsdoc",
22
- "jsdoc-mermaid": "1.0.0"
20
+ "eslint": "^9.7.0"
23
21
  },
24
22
  "dependencies": {
25
23
  "@eslint-community/eslint-plugin-eslint-comments": "^4.3.0",
24
+ "@eslint-react/eslint-plugin": "^1.5.28",
26
25
  "@stylistic/eslint-plugin": "^2.3.0",
26
+ "@typescript-eslint/parser": "^8.0.0-alpha.47",
27
+ "eslint-plugin-depend": "^0.9.0",
27
28
  "eslint-plugin-import-x": "^3.0.1",
28
- "eslint-plugin-jsdoc": "^48.7.0",
29
+ "eslint-plugin-jsdoc": "^48.8.3",
29
30
  "eslint-plugin-no-secrets": "^1.0.2",
30
31
  "eslint-plugin-perfectionist": "^2.11.0",
31
- "eslint-plugin-promise": "^6.4.0",
32
- "eslint-plugin-react": "github:jsx-eslint/eslint-plugin-react#pull/3759",
32
+ "eslint-plugin-promise": "^6.5.1",
33
33
  "eslint-plugin-redos": "^4.4.5",
34
34
  "eslint-plugin-regexp": "^2.6.0",
35
35
  "eslint-plugin-security": "^3.0.1",
@@ -40,5 +40,9 @@
40
40
  },
41
41
  "peerDependencies": {
42
42
  "eslint": "^9.4.0"
43
+ },
44
+ "overrides": {
45
+ "@typescript-eslint/type-utils": "^8.0.0-alpha.47",
46
+ "@typescript-eslint/utils": "^8.0.0-alpha.47"
43
47
  }
44
48
  }
package/plugins.js CHANGED
@@ -1,6 +1,8 @@
1
1
  /* eslint-disable import-x/max-dependencies -- collection file */
2
2
  import eslintComments from "@eslint-community/eslint-plugin-eslint-comments";
3
+ import react from "@eslint-react/eslint-plugin";
3
4
  import stylistic from "@stylistic/eslint-plugin";
5
+ import depend from "eslint-plugin-depend";
4
6
  // import github from "eslint-plugin-github";
5
7
  import importX from "eslint-plugin-import-x";
6
8
  import jsdoc from "eslint-plugin-jsdoc";
@@ -9,7 +11,6 @@ import noSecrets from "eslint-plugin-no-secrets";
9
11
  // import noUnsanitized from "eslint-plugin-no-unsanitized";
10
12
  import perfectionist from "eslint-plugin-perfectionist";
11
13
  import promise from "eslint-plugin-promise";
12
- import react from "eslint-plugin-react";
13
14
  import redos from "eslint-plugin-redos";
14
15
  import regexp from "eslint-plugin-regexp";
15
16
  import security from "eslint-plugin-security";
@@ -26,6 +27,7 @@ const plugins = {
26
27
  // "jsx-a11y": jsxA11y,
27
28
  "no-secrets": noSecrets,
28
29
  // "no-unsanitized": noUnsanitized,
30
+ depend,
29
31
  perfectionist,
30
32
  promise,
31
33
  react,
package/rules/_exports.js CHANGED
@@ -1,3 +1,4 @@
1
+ export { default as dependRules } from "./depend.js";
1
2
  export { default as eslintCommentsRules } from "./eslint-comments.js";
2
3
  // export { default as githubRules } from "./github.js";
3
4
  export { default as importXRules } from "./import-x.js";
@@ -0,0 +1,5 @@
1
+ const dependRules = {
2
+ "depend/ban-dependencies": "error"
3
+ };
4
+
5
+ export default dependRules;
@@ -34,7 +34,7 @@ const styleGuideRules = {
34
34
  "import-x/no-namespace": [
35
35
  "error",
36
36
  {
37
- ignore: ["{./**/,**/}_exports.?(*.)js"]
37
+ ignore: ["{./**/,**/}_exports.?(*.)js", "@typescript-eslint/parser"]
38
38
  }
39
39
  ],
40
40
  "import-x/no-unassigned-import": "error",
package/rules/jsdoc.js CHANGED
@@ -1,9 +1,14 @@
1
1
  const jsdocRules = {
2
2
  "jsdoc/check-access": "warn",
3
3
  "jsdoc/check-alignment": "warn",
4
- // TODO [eslint-plugin-jsdoc@>=49]: enable when https://github.com/eslint/eslint/issues/14745 is fixed
4
+ // TODO [eslint-plugin-jsdoc@>=49]: enable when https://github.com/eslint/eslint/issues/14745 and https://github.com/gajus/eslint-plugin-jsdoc/issues/928 are closed
5
5
  "jsdoc/check-examples": "off",
6
- "jsdoc/check-indentation": "warn",
6
+ "jsdoc/check-indentation": [
7
+ "warn",
8
+ {
9
+ excludeTags: ["example", "typedef"]
10
+ }
11
+ ],
7
12
  "jsdoc/check-line-alignment": "off",
8
13
  "jsdoc/check-param-names": "warn",
9
14
  "jsdoc/check-property-names": "warn",
@@ -14,6 +19,7 @@ const jsdocRules = {
14
19
  definedTags: ["category", "component"]
15
20
  }
16
21
  ],
22
+ "jsdoc/check-template-names": "warn",
17
23
  "jsdoc/check-types": "warn",
18
24
  "jsdoc/check-values": "warn",
19
25
  "jsdoc/convert-to-jsdoc-comments": [
@@ -137,8 +143,20 @@ const jsdocRules = {
137
143
  "jsdoc/require-jsdoc": [
138
144
  "warn",
139
145
  {
146
+ contexts: [
147
+ `
148
+ :not(
149
+ :matches(
150
+ CallExpression > ObjectExpression > Property,
151
+ ArrayExpression:has(Literal ~ ArrowFunctionExpression),
152
+ CallExpression,
153
+ Property > AssignmentPattern
154
+ )
155
+ ) > ArrowFunctionExpression
156
+ `.replaceAll(/\s/gu, "")
157
+ ],
140
158
  require: {
141
- ArrowFunctionExpression: true,
159
+ ArrowFunctionExpression: false,
142
160
  ClassDeclaration: true,
143
161
  ClassExpression: true,
144
162
  FunctionDeclaration: true,
@@ -0,0 +1,5 @@
1
+ export { default as coreRules } from "./core.js";
2
+ export { default as debugRules } from "./debug.js";
3
+ export { default as domRules } from "./dom.js";
4
+ export { default as hooksExtraRules } from "./hooks-extra.js";
5
+ export { default as namingConventionRules } from "./naming-convention.js";
@@ -0,0 +1,45 @@
1
+ const coreRules = {
2
+ "react/avoid-shorthand-boolean": "off",
3
+ "react/avoid-shorthand-fragment": "off",
4
+ "react/ensure-forward-ref-using-ref": "error",
5
+ "react/no-access-state-in-setstate": "error",
6
+ "react/no-array-index-key": "error",
7
+ "react/no-children-count": "error",
8
+ "react/no-children-for-each": "error",
9
+ "react/no-children-map": "error",
10
+ "react/no-children-only": "error",
11
+ "react/no-children-prop": "error",
12
+ "react/no-children-to-array": "error",
13
+ "react/no-class-component": "error",
14
+ "react/no-clone-element": "error",
15
+ "react/no-comment-textnodes": "error",
16
+ "react/no-component-will-mount": "error",
17
+ "react/no-component-will-receive-props": "error",
18
+ "react/no-component-will-update": "error",
19
+ "react/no-create-ref": "error",
20
+ "react/no-direct-mutation-state": "error",
21
+ "react/no-duplicate-key": "error",
22
+ "react/no-leaked-conditional-rendering": "error",
23
+ "react/no-missing-component-display-name": "error",
24
+ "react/no-missing-key": "error",
25
+ "react/no-nested-components": "error",
26
+ "react/no-redundant-should-component-update": "error",
27
+ "react/no-set-state-in-component-did-mount": "error",
28
+ "react/no-set-state-in-component-did-update": "error",
29
+ "react/no-set-state-in-component-will-update": "error",
30
+ "react/no-string-refs": "error",
31
+ "react/no-unsafe-component-will-mount": "error",
32
+ "react/no-unsafe-component-will-receive-props": "error",
33
+ "react/no-unsafe-component-will-update": "error",
34
+ "react/no-unstable-context-value": "error",
35
+ "react/no-unstable-default-props": "error",
36
+ "react/no-unused-class-component-members": "error",
37
+ "react/no-unused-state": "error",
38
+ "react/no-useless-fragment": "error",
39
+ "react/prefer-destructuring-assignment": "error",
40
+ "react/prefer-read-only-props": "error",
41
+ "react/prefer-shorthand-boolean": "error",
42
+ "react/prefer-shorthand-fragment": "error"
43
+ };
44
+
45
+ export default coreRules;
@@ -0,0 +1,7 @@
1
+ const debugRules = {
2
+ "react/debug/class-component": "off",
3
+ "react/debug/function-component": "off",
4
+ "react/debug/react-hooks": "off"
5
+ };
6
+
7
+ export default debugRules;
@@ -0,0 +1,15 @@
1
+ const domRules = {
2
+ "react/dom/no-children-in-void-dom-elements": "error",
3
+ "react/dom/no-dangerously-set-innerhtml": "error",
4
+ "react/dom/no-dangerously-set-innerhtml-with-children": "error",
5
+ "react/dom/no-find-dom-node": "error",
6
+ "react/dom/no-missing-button-type": "error",
7
+ "react/dom/no-missing-iframe-sandbox": "error",
8
+ "react/dom/no-namespace": "error",
9
+ "react/dom/no-render-return-value": "error",
10
+ "react/dom/no-script-url": "error",
11
+ "react/dom/no-unsafe-iframe-sandbox": "error",
12
+ "react/dom/no-unsafe-target-blank": "error"
13
+ };
14
+
15
+ export default domRules;
@@ -0,0 +1,10 @@
1
+ const hooksExtraRules = {
2
+ "react/hooks-extra/ensure-custom-hooks-using-other-hooks": "error",
3
+ "react/hooks-extra/ensure-use-callback-has-non-empty-deps": "error",
4
+ "react/hooks-extra/ensure-use-memo-has-non-empty-deps": "error",
5
+ "react/hooks-extra/no-direct-set-state-in-use-effect": "error",
6
+ "react/hooks-extra/no-direct-set-state-in-use-layout-effect": "error",
7
+ "react/hooks-extra/prefer-use-state-lazy-initialization": "error"
8
+ };
9
+
10
+ export default hooksExtraRules;
@@ -0,0 +1,20 @@
1
+ const namingConventionRules = {
2
+ "react/naming-convention/component-name": [
3
+ "error",
4
+ {
5
+ excepts: [],
6
+ rule: "PascalCase"
7
+ }
8
+ ],
9
+ "react/naming-convention/filename": ["error", { rule: "kebab-case" }],
10
+ "react/naming-convention/filename-extension": [
11
+ "error",
12
+ {
13
+ allow: "as-needed",
14
+ extensions: [".jsx", ".tsx"]
15
+ }
16
+ ],
17
+ "react/naming-convention/use-state": "error"
18
+ };
19
+
20
+ export default namingConventionRules;
package/rules/react.js CHANGED
@@ -1,107 +1,12 @@
1
- const maxDepth = 10;
1
+ import * as reactRuleSets from "./react/_exports.js";
2
2
 
3
- const reactRules = {
4
- "react/boolean-prop-naming": "error",
5
- "react/button-has-type": "error",
6
- "react/default-props-match-prop-types": "error",
7
- "react/destructuring-assignment": "error",
8
- "react/display-name": "error",
9
- "react/forbid-component-props": "off",
10
- "react/forbid-dom-props": "error",
11
- "react/forbid-elements": "error",
12
- "react/forbid-foreign-prop-types": "error",
13
- "react/forbid-prop-types": "error",
14
- "react/function-component-definition": [
15
- "error",
16
- {
17
- namedComponents: "arrow-function",
18
- unnamedComponents: "arrow-function"
19
- }
20
- ],
21
- "react/hook-use-state": ["error", { allowDestructuredState: true }],
22
- "react/iframe-missing-sandbox": "error",
23
- "react/jsx-boolean-value": "error",
24
- "react/jsx-filename-extension": [
25
- "error",
26
- {
27
- allow: "as-needed",
28
- extensions: [".jsx"],
29
- ignoreFilesWithoutCode: true
30
- }
31
- ],
32
- "react/jsx-fragments": ["error", "syntax"],
33
- "react/jsx-handler-names": "error",
34
- "react/jsx-key": "error",
35
- "react/jsx-max-depth": ["error", { max: maxDepth }],
36
- "react/jsx-no-bind": "error",
37
- "react/jsx-no-comment-textnodes": "error",
38
- "react/jsx-no-constructed-context-values": "error",
39
- "react/jsx-no-duplicate-props": "error",
40
- "react/jsx-no-leaked-render": "error",
41
- "react/jsx-no-literals": "off",
42
- "react/jsx-no-script-url": "error",
43
- "react/jsx-no-target-blank": [
44
- "error",
45
- {
46
- allowReferrer: false,
47
- enforceDynamicLinks: "always",
48
- forms: false,
49
- links: true,
50
- warnOnSpreadAttributes: true
51
- }
52
- ],
53
- "react/jsx-no-undef": "error",
54
- "react/jsx-no-useless-fragment": "error",
55
- "react/jsx-props-no-spreading": "off",
56
- "react/jsx-uses-react": "error",
57
- "react/jsx-uses-vars": "error",
58
- "react/no-access-state-in-setstate": "error",
59
- "react/no-adjacent-inline-elements": "error",
60
- "react/no-array-index-key": "off",
61
- "react/no-arrow-function-lifecycle": "off",
62
- "react/no-children-prop": "error",
63
- "react/no-danger": "error",
64
- "react/no-danger-with-children": "error",
65
- "react/no-deprecated": "error",
66
- "react/no-did-mount-set-state": "error",
67
- "react/no-did-update-set-state": "error",
68
- "react/no-direct-mutation-state": "error",
69
- "react/no-find-dom-node": "error",
70
- "react/no-invalid-html-attribute": "error",
71
- "react/no-is-mounted": "error",
72
- "react/no-multi-comp": ["error", { ignoreStateless: false }],
73
- "react/no-namespace": "error",
74
- "react/no-object-type-as-default-prop": "error",
75
- "react/no-redundant-should-component-update": "error",
76
- "react/no-render-return-value": "error",
77
- "react/no-set-state": "off",
78
- "react/no-string-refs": "error",
79
- "react/no-this-in-sfc": "error",
80
- "react/no-typos": "error",
81
- "react/no-unescaped-entities": "error",
82
- "react/no-unknown-property": "error",
83
- "react/no-unsafe": "error",
84
- "react/no-unstable-nested-components": "error",
85
- "react/no-unused-class-component-methods": "error",
86
- "react/no-unused-prop-types": "error",
87
- "react/no-unused-state": "error",
88
- "react/no-will-update-set-state": "error",
89
- "react/prefer-es6-class": ["error", "always"],
90
- "react/prefer-exact-props": "error",
91
- "react/prefer-read-only-props": "error",
92
- "react/prefer-stateless-function": "error",
93
- "react/prop-types": "off",
94
- "react/react-in-jsx-scope": "off",
95
- "react/require-default-props": "error",
96
- "react/require-optimization": "error",
97
- "react/require-render-return": "error",
98
- "react/sort-comp": "off",
99
- "react/sort-default-props": "off",
100
- "react/sort-prop-types": "off",
101
- "react/state-in-constructor": ["error", "never"],
102
- "react/static-property-placement": "error",
103
- "react/style-prop-object": "error",
104
- "react/void-dom-elements-no-children": "error"
105
- };
3
+ const reactRules = Object.values(reactRuleSets)
4
+ .reduce(
5
+ (allRules, ruleSet) => ({
6
+ ...allRules,
7
+ ...ruleSet
8
+ }),
9
+ {}
10
+ );
106
11
 
107
12
  export default reactRules;
@@ -4,7 +4,7 @@ const maxClassesPerFile = 1;
4
4
  const maxDepth = 8;
5
5
  const maxLinesPerFile = 500;
6
6
  const maxLinesPerFunction = 100;
7
- const maxNestedCallbacks = 4;
7
+ const maxNestedCallbacks = 10;
8
8
  const maxParameters = 3;
9
9
  const maxStatements = 20;
10
10
 
@@ -0,0 +1,47 @@
1
+ import { join } from "@std/path";
2
+
3
+ const {
4
+ cwd,
5
+ readTextFile,
6
+ writeTextFile
7
+ } = Deno;
8
+
9
+ const packageJsonFilePath = join(cwd(), "package.json");
10
+ const packageJsonFileContent = await readTextFile(packageJsonFilePath);
11
+ const packageJson = JSON.parse(packageJsonFileContent);
12
+
13
+ const importMapFilePath = join(cwd(), "import-map.json");
14
+ const importMapFileContent = await readTextFile(importMapFilePath);
15
+ const importMap = JSON.parse(importMapFileContent);
16
+
17
+ const collator = new Intl.Collator("en", {
18
+ numeric: true
19
+ });
20
+
21
+ const updatedImportMap = {
22
+ ...importMap,
23
+ imports: Object.fromEntries(
24
+
25
+ Object.entries({
26
+ ...importMap.imports,
27
+ ...Object.fromEntries(
28
+ Object.entries(
29
+ packageJson.dependencies
30
+ )
31
+ .map(([packageName, packageVersion]) => [packageName, `npm:${packageName}@${packageVersion}`])
32
+ )
33
+ })
34
+ .toSorted((
35
+ [packageNameA],
36
+ [packageNameB]
37
+ ) => collator.compare(
38
+ packageNameA,
39
+ packageNameB
40
+ ))
41
+ )
42
+ };
43
+
44
+ await writeTextFile(
45
+ importMapFilePath,
46
+ JSON.stringify(updatedImportMap, null, "\t")
47
+ );
@@ -0,0 +1,46 @@
1
+ import { join } from "@std/path";
2
+
3
+ const {
4
+ cwd,
5
+ readTextFile,
6
+ writeTextFile
7
+ } = Deno;
8
+
9
+ const denoJsonFilePath = join(cwd(), "deno.json");
10
+ const denoJsonFileContent = await readTextFile(denoJsonFilePath);
11
+ const denoJson = JSON.parse(denoJsonFileContent);
12
+
13
+ const tsconfigFilePath = join(cwd(), "tsconfig.json");
14
+ const tsconfigFileContent = await readTextFile(tsconfigFilePath);
15
+ const tsconfig = JSON.parse(tsconfigFileContent);
16
+
17
+ const collator = new Intl.Collator("en", {
18
+ numeric: true
19
+ });
20
+
21
+ const updatedTsconfig = {
22
+ ...tsconfig,
23
+ compilerOptions: Object.fromEntries(
24
+ Object.entries({
25
+ ...tsconfig.compilerOptions,
26
+ ...Object.fromEntries(
27
+ Object.entries(
28
+ denoJson.compilerOptions
29
+ )
30
+ .filter(([key]) => key !== "lib")
31
+ )
32
+ })
33
+ .toSorted((
34
+ [keyA],
35
+ [keyB]
36
+ ) => collator.compare(
37
+ keyA,
38
+ keyB
39
+ ))
40
+ )
41
+ };
42
+
43
+ await writeTextFile(
44
+ tsconfigFilePath,
45
+ JSON.stringify(updatedTsconfig, null, "\t")
46
+ );
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "allowJs": true,
4
+ "allowUnreachableCode": false,
5
+ "allowUnusedLabels": false,
6
+ "alwaysStrict": true,
7
+ "checkJs": true,
8
+ "exactOptionalPropertyTypes": true,
9
+ "jsx": "react-jsx",
10
+ "jsxImportSource": "preact",
11
+ "noErrorTruncation": true,
12
+ "noFallthroughCasesInSwitch": false,
13
+ "noImplicitAny": true,
14
+ "noImplicitOverride": true,
15
+ "noImplicitReturns": true,
16
+ "noImplicitThis": true,
17
+ "noPropertyAccessFromIndexSignature": false,
18
+ "noUncheckedIndexedAccess": false,
19
+ "noUnusedLocals": false,
20
+ "noUnusedParameters": false,
21
+ "strict": true
22
+ }
23
+ }