@dvukovic/style-guide 0.26.0 → 0.28.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.
@@ -0,0 +1,31 @@
1
+ export namespace noTypesInTsx {
2
+ function create(context: any): {
3
+ TSInterfaceDeclaration?: undefined;
4
+ TSTypeAliasDeclaration?: undefined;
5
+ } | {
6
+ TSInterfaceDeclaration: (node: any) => void;
7
+ TSTypeAliasDeclaration: (node: any) => void;
8
+ };
9
+ namespace meta {
10
+ namespace docs {
11
+ let description: string;
12
+ }
13
+ namespace messages {
14
+ let noTypesInTsx: string;
15
+ }
16
+ let schema: {
17
+ additionalProperties: boolean;
18
+ properties: {
19
+ directories: {
20
+ default: string[];
21
+ items: {
22
+ type: string;
23
+ };
24
+ type: string;
25
+ };
26
+ };
27
+ type: string;
28
+ }[];
29
+ let type: string;
30
+ }
31
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dvukovic/style-guide",
3
- "version": "0.26.0",
3
+ "version": "0.28.0",
4
4
  "description": "My own style guide",
5
5
  "repository": {
6
6
  "type": "git",
@@ -60,69 +60,69 @@
60
60
  "test": "vitest run"
61
61
  },
62
62
  "dependencies": {
63
- "@clack/prompts": "1.1.0",
64
- "@eslint-community/eslint-plugin-eslint-comments": "4.7.1",
65
- "@eslint/config-helpers": "0.5.3",
66
- "@next/eslint-plugin-next": "16.2.1",
63
+ "@clack/prompts": "1.7.0",
64
+ "@eslint-community/eslint-plugin-eslint-comments": "4.7.2",
65
+ "@eslint/config-helpers": "0.6.0",
66
+ "@next/eslint-plugin-next": "16.2.10",
67
67
  "@stylistic/eslint-plugin": "5.10.0",
68
- "@tanstack/eslint-plugin-query": "5.94.5",
69
- "@typescript-eslint/parser": "8.57.1",
70
- "@vitest/eslint-plugin": "1.6.12",
68
+ "@tanstack/eslint-plugin-query": "5.101.2",
69
+ "@typescript-eslint/parser": "8.63.0",
70
+ "@vitest/eslint-plugin": "1.6.23",
71
71
  "eslint-plugin-array-func": "5.1.1",
72
- "eslint-plugin-baseline-js": "0.6.1",
73
- "eslint-plugin-import-x": "4.16.2",
74
- "eslint-plugin-jest": "29.15.0",
72
+ "eslint-plugin-baseline-js": "0.7.0",
73
+ "eslint-plugin-import-x": "4.17.1",
74
+ "eslint-plugin-jest": "29.15.4",
75
75
  "eslint-plugin-mobx": "0.0.14",
76
- "eslint-plugin-n": "17.24.0",
77
- "eslint-plugin-package-json": "0.91.0",
78
- "eslint-plugin-perfectionist": "5.7.0",
79
- "eslint-plugin-playwright": "2.10.1",
80
- "eslint-plugin-promise": "7.2.1",
76
+ "eslint-plugin-n": "18.2.2",
77
+ "eslint-plugin-package-json": "1.5.0",
78
+ "eslint-plugin-perfectionist": "5.10.0",
79
+ "eslint-plugin-playwright": "2.10.5",
80
+ "eslint-plugin-promise": "7.3.0",
81
81
  "eslint-plugin-react": "7.37.5",
82
- "eslint-plugin-react-hooks": "7.0.1",
82
+ "eslint-plugin-react-hooks": "7.1.1",
83
83
  "eslint-plugin-security-node": "1.1.4",
84
- "eslint-plugin-sonarjs": "4.0.2",
85
- "eslint-plugin-storybook": "10.3.1",
86
- "eslint-plugin-turbo": "2.8.20",
87
- "eslint-plugin-unicorn": "63.0.0",
84
+ "eslint-plugin-sonarjs": "4.1.0",
85
+ "eslint-plugin-storybook": "10.5.0",
86
+ "eslint-plugin-turbo": "2.10.4",
87
+ "eslint-plugin-unicorn": "71.1.0",
88
88
  "eslint-plugin-unused-imports": "4.4.1",
89
- "globals": "17.4.0",
89
+ "globals": "17.7.0",
90
90
  "jsonc-eslint-parser": "3.1.0",
91
91
  "postcss-resolve-nested-selector": "0.1.6",
92
- "postcss-selector-parser": "7.1.1",
92
+ "postcss-selector-parser": "7.1.4",
93
93
  "prettier-plugin-embed": "0.5.1",
94
- "prettier-plugin-jsdoc": "1.8.0",
94
+ "prettier-plugin-jsdoc": "1.8.1",
95
95
  "prettier-plugin-packagejson": "3.0.2",
96
96
  "prettier-plugin-prisma": "5.0.0",
97
- "prettier-plugin-sh": "0.18.0",
97
+ "prettier-plugin-sh": "0.19.0",
98
98
  "prettier-plugin-sql": "0.20.0",
99
- "prettier-plugin-tailwindcss": "0.7.2",
99
+ "prettier-plugin-tailwindcss": "0.8.0",
100
100
  "prettier-plugin-toml": "2.0.6",
101
101
  "stylelint-order": "8.1.1",
102
- "typescript-eslint": "8.57.1"
102
+ "typescript-eslint": "8.63.0"
103
103
  },
104
104
  "devDependencies": {
105
- "@release-it/conventional-changelog": "10.0.6",
106
- "@types/node": "25.5.0",
105
+ "@release-it/conventional-changelog": "11.0.1",
106
+ "@types/node": "26.1.1",
107
107
  "@types/semver": "7.7.1",
108
- "cspell": "9.7.0",
109
- "eslint": "9.39.4",
110
- "knip": "6.0.1",
111
- "prettier": "3.8.1",
112
- "release-it": "19.2.4",
113
- "semver": "7.7.4",
114
- "storybook": "10.3.1",
115
- "stylelint": "17.5.0",
116
- "typescript": "5.9.3",
117
- "vitest": "4.1.0"
108
+ "cspell": "10.0.1",
109
+ "eslint": "10.7.0",
110
+ "knip": "6.26.0",
111
+ "prettier": "3.9.5",
112
+ "release-it": "20.2.1",
113
+ "semver": "7.8.5",
114
+ "storybook": "10.5.0",
115
+ "stylelint": "17.14.0",
116
+ "typescript": "6.0.3",
117
+ "vitest": "4.1.10"
118
118
  },
119
119
  "peerDependencies": {
120
120
  "cspell": "10",
121
- "eslint": "^9",
121
+ "eslint": "^9 || ^10",
122
122
  "knip": ">=5",
123
123
  "prettier": "3",
124
124
  "stylelint": ">=16",
125
- "typescript": "5"
125
+ "typescript": "5 || 6"
126
126
  },
127
127
  "peerDependenciesMeta": {
128
128
  "cspell": {
@@ -149,7 +149,7 @@
149
149
  "node": ">=24.0.0"
150
150
  },
151
151
  "volta": {
152
- "node": "24.4.1"
152
+ "node": "24.18.0"
153
153
  },
154
154
  "publishConfig": {
155
155
  "access": "public",
package/src/cli/init.js CHANGED
@@ -87,7 +87,7 @@ async function installPackages(tools, packageManager) {
87
87
  }
88
88
 
89
89
  const packages = missingPackages.join(" ")
90
- const installCmd =
90
+ const installCommand =
91
91
  packageManager === "npm"
92
92
  ? `npm install -D ${packages}`
93
93
  : `${packageManager} add -D ${packages}`
@@ -98,11 +98,11 @@ async function installPackages(tools, packageManager) {
98
98
 
99
99
  try {
100
100
  // eslint-disable-next-line sonarjs/os-command -- User-confirmed install command
101
- execSync(installCmd, { stdio: "pipe" })
101
+ execSync(installCommand, { stdio: "pipe" })
102
102
  spinner.stop("Packages installed")
103
103
  } catch {
104
104
  spinner.stop("Failed to install. Please run manually:")
105
- clack.log.info(` ${installCmd}`)
105
+ clack.log.info(` ${installCommand}`)
106
106
  }
107
107
  }
108
108
 
@@ -158,11 +158,7 @@ async function updatePackageJsonScripts(tools, packageManager) {
158
158
  export async function runInit() {
159
159
  const tools = await promptToolSelection()
160
160
 
161
- let eslintOptions = null
162
-
163
- if (tools.includes("eslint")) {
164
- eslintOptions = await promptESLintOptions()
165
- }
161
+ const eslintOptions = tools.includes("eslint") ? await promptESLintOptions() : null
166
162
 
167
163
  const packageManager = detectPackageManager()
168
164
 
@@ -4,6 +4,7 @@ import { noCommentedOutCode } from "../rules/no-commented-out-code/no-commented-
4
4
  import { noCrossModuleImports } from "../rules/no-cross-module-imports/no-cross-module-imports.js"
5
5
  import { noInstanceofError } from "../rules/no-instanceof-error/no-instanceof-error.js"
6
6
  import { noT } from "../rules/no-t/no-t.js"
7
+ import { noTypesInTsx } from "../rules/no-types-in-tsx/no-types-in-tsx.js"
7
8
 
8
9
  const dvukovicPlugin = {
9
10
  rules: {
@@ -13,6 +14,7 @@ const dvukovicPlugin = {
13
14
  "no-cross-module-imports": noCrossModuleImports,
14
15
  "no-instanceof-error": noInstanceofError,
15
16
  "no-t": noT,
17
+ "no-types-in-tsx": noTypesInTsx,
16
18
  },
17
19
  }
18
20
 
@@ -37,5 +39,6 @@ export const dvukovicNextjs = {
37
39
  rules: {
38
40
  "dvukovic/nextjs-export-name": "error",
39
41
  "dvukovic/no-cross-module-imports": "error",
42
+ "dvukovic/no-types-in-tsx": "error",
40
43
  },
41
44
  }
@@ -89,7 +89,6 @@ export const packageJson = {
89
89
  "package-json/valid-name": "error",
90
90
  "package-json/valid-optionalDependencies": "error",
91
91
  "package-json/valid-os": "error",
92
- "package-json/valid-package-definition": "error",
93
92
  "package-json/valid-packageManager": "error",
94
93
  "package-json/valid-peerDependencies": "error",
95
94
  "package-json/valid-private": "error",
@@ -6,7 +6,6 @@ export const reactHooks = {
6
6
  "react-hooks": plugin,
7
7
  },
8
8
  rules: {
9
- "react-hooks/component-hook-factories": "error",
10
9
  "react-hooks/config": "error",
11
10
  "react-hooks/error-boundaries": "error",
12
11
  "react-hooks/gating": "error",
@@ -20,7 +20,6 @@ export const sonarjsAws = {
20
20
  "sonarjs/aws-s3-bucket-granted-access": "error",
21
21
  "sonarjs/aws-s3-bucket-insecure-http": "error",
22
22
  "sonarjs/aws-s3-bucket-public-access": "error",
23
- "sonarjs/aws-s3-bucket-server-encryption": "error",
24
23
  "sonarjs/aws-s3-bucket-versioning": "error",
25
24
  "sonarjs/aws-sagemaker-unencrypted-notebook": "error",
26
25
  "sonarjs/aws-sns-unencrypted-topics": "error",
@@ -35,6 +35,7 @@ export const sonarjs = {
35
35
  "sonarjs/disabled-auto-escaping": "error",
36
36
  "sonarjs/disabled-resource-integrity": "error",
37
37
  "sonarjs/disabled-timeout": "error",
38
+ "sonarjs/dompurify-unsafe-config": "error",
38
39
  "sonarjs/duplicates-in-character-class": "error",
39
40
  "sonarjs/empty-string-repetition": "error",
40
41
  "sonarjs/encryption-secure-mode": "error",
@@ -80,6 +81,7 @@ export const sonarjs = {
80
81
  "sonarjs/no-control-regex": "error",
81
82
  "sonarjs/no-delete-var": "error",
82
83
  "sonarjs/no-duplicate-in-composite": "error",
84
+ "sonarjs/no-duplicate-test-title": "error",
83
85
  "sonarjs/no-duplicated-branches": "error",
84
86
  "sonarjs/no-element-overwrite": "error",
85
87
  "sonarjs/no-empty-after-reluctant": "error",
@@ -88,6 +90,7 @@ export const sonarjs = {
88
90
  "sonarjs/no-empty-collection": "error",
89
91
  "sonarjs/no-empty-group": "error",
90
92
  "sonarjs/no-empty-test-file": "error",
93
+ "sonarjs/no-empty-test-title": "error",
91
94
  "sonarjs/no-equals-in-for-termination": "error",
92
95
  "sonarjs/no-exclusive-tests": "error",
93
96
  "sonarjs/no-extra-arguments": "error",
@@ -189,6 +192,7 @@ export const sonarjs = {
189
192
  "sonarjs/stateful-regex": "error",
190
193
  "sonarjs/strict-transport-security": "error",
191
194
  "sonarjs/strings-comparison": "error",
195
+ "sonarjs/super-linear-regex": "error",
192
196
  "sonarjs/table-header": "error",
193
197
  "sonarjs/table-header-reference": "error",
194
198
  "sonarjs/test-check-exception": "error",
@@ -8,6 +8,7 @@ export const tanstackQuery = {
8
8
  rules: {
9
9
  "@tanstack/query/exhaustive-deps": "error",
10
10
  "@tanstack/query/no-rest-destructuring": "error",
11
+ "@tanstack/query/prefer-query-options": "error",
11
12
  "@tanstack/query/stable-query-client": "error",
12
13
  },
13
14
  }
@@ -6,14 +6,15 @@ export const unicorn = {
6
6
  unicorn: plugin,
7
7
  },
8
8
  rules: {
9
- "unicorn/better-regex": "error",
10
9
  "unicorn/catch-error-name": "error",
11
10
  "unicorn/consistent-date-clone": "error",
12
11
  "unicorn/consistent-destructuring": "error",
13
12
  "unicorn/consistent-empty-array-spread": "error",
14
13
  "unicorn/consistent-existence-index-check": "error",
15
14
  "unicorn/consistent-function-scoping": "error",
15
+ "unicorn/consistent-json-file-read": "error",
16
16
  "unicorn/custom-error-definition": "error",
17
+ "unicorn/dom-node-dataset": "error",
17
18
  "unicorn/empty-brace-spaces": "error",
18
19
  "unicorn/error-message": "error",
19
20
  "unicorn/escape-case": "error",
@@ -26,35 +27,77 @@ export const unicorn = {
26
27
  kebabCase: true,
27
28
  pascalCase: true,
28
29
  },
30
+ checkDirectories: false,
29
31
  },
30
32
  ],
31
33
  "unicorn/isolated-functions": "error",
34
+ "unicorn/name-replacements": [
35
+ "error",
36
+ {
37
+ ignore: [
38
+ "utils",
39
+ "Utils",
40
+ "Arg",
41
+ "Args",
42
+ "Param",
43
+ "Params",
44
+ "Prev",
45
+ "Prop",
46
+ "Props",
47
+ "Ref",
48
+ "Refs",
49
+ "arg",
50
+ "args",
51
+ "env",
52
+ "param",
53
+ "params",
54
+ "prev",
55
+ "prop",
56
+ "props",
57
+ "ref",
58
+ "refs",
59
+ ],
60
+ },
61
+ ],
32
62
  "unicorn/new-for-builtins": "error",
33
63
  "unicorn/no-abusive-eslint-disable": "error",
34
64
  "unicorn/no-accessor-recursion": "error",
35
65
  "unicorn/no-anonymous-default-export": "error",
36
66
  "unicorn/no-array-callback-reference": "error",
67
+ "unicorn/no-array-fill-with-reference-type": "error",
68
+ "unicorn/no-array-from-fill": "error",
37
69
  "unicorn/no-array-method-this-argument": "error",
38
70
  "unicorn/no-array-reduce": "error",
39
71
  "unicorn/no-array-reverse": "error",
72
+ "unicorn/no-array-sort-for-min-max": "error",
73
+ "unicorn/no-array-splice": "error",
40
74
  "unicorn/no-await-expression-member": "error",
41
75
  "unicorn/no-await-in-promise-methods": "error",
76
+ "unicorn/no-chained-comparison": "error",
42
77
  "unicorn/no-console-spaces": "error",
78
+ "unicorn/no-constant-zero-expression": "error",
43
79
  "unicorn/no-document-cookie": "error",
80
+ "unicorn/no-double-comparison": "error",
81
+ "unicorn/no-duplicate-logical-operands": "error",
82
+ "unicorn/no-duplicate-set-values": "error",
44
83
  "unicorn/no-empty-file": "error",
45
84
  "unicorn/no-for-loop": "error",
46
85
  "unicorn/no-immediate-mutation": "error",
86
+ "unicorn/no-impossible-length-comparison": "error",
47
87
  "unicorn/no-instanceof-builtins": "error",
48
88
  "unicorn/no-invalid-fetch-options": "error",
49
89
  "unicorn/no-invalid-remove-event-listener": "error",
50
90
  "unicorn/no-lonely-if": "error",
51
91
  "unicorn/no-magic-array-flat-depth": "error",
92
+ "unicorn/no-mismatched-map-key": "error",
52
93
  "unicorn/no-named-default": "error",
53
94
  "unicorn/no-negation-in-equality-check": "error",
54
95
  "unicorn/no-new-array": "error",
55
96
  "unicorn/no-new-buffer": "error",
56
97
  "unicorn/no-object-as-default-parameter": "error",
98
+ "unicorn/no-object-methods-with-collections": "error",
57
99
  "unicorn/no-process-exit": "error",
100
+ "unicorn/no-return-array-push": "error",
58
101
  "unicorn/no-single-promise-in-promise-methods": "error",
59
102
  "unicorn/no-static-only-class": "error",
60
103
  "unicorn/no-thenable": "error",
@@ -63,12 +106,21 @@ export const unicorn = {
63
106
  "unicorn/no-unnecessary-array-flat-depth": "error",
64
107
  "unicorn/no-unnecessary-array-splice-count": "error",
65
108
  "unicorn/no-unnecessary-await": "error",
109
+ "unicorn/no-unnecessary-nested-ternary": "error",
66
110
  "unicorn/no-unnecessary-polyfills": "error",
67
111
  "unicorn/no-unnecessary-slice-end": "error",
68
112
  "unicorn/no-unreadable-array-destructuring": "error",
69
113
  "unicorn/no-unreadable-iife": "error",
114
+ "unicorn/no-unsafe-buffer-conversion": "error",
115
+ "unicorn/no-unsafe-dom-html": "error",
116
+ "unicorn/no-unsafe-property-key": "error",
117
+ "unicorn/no-unsafe-string-replacement": "error",
118
+ "unicorn/no-unused-array-method-return": "error",
70
119
  "unicorn/no-unused-properties": "error",
71
120
  "unicorn/no-useless-collection-argument": "error",
121
+ "unicorn/no-useless-continue": "error",
122
+ "unicorn/no-useless-delete-check": "error",
123
+ "unicorn/no-useless-else": "error",
72
124
  "unicorn/no-useless-error-capture-stack-trace": "error",
73
125
  "unicorn/no-useless-fallback-in-spread": "error",
74
126
  "unicorn/no-useless-length-check": "error",
@@ -78,44 +130,69 @@ export const unicorn = {
78
130
  "unicorn/no-zero-fractions": "error",
79
131
  "unicorn/number-literal-case": "error",
80
132
  "unicorn/numeric-separators-style": "error",
133
+ "unicorn/prefer-abort-signal-any": "error",
134
+ "unicorn/prefer-abort-signal-timeout": "error",
135
+ "unicorn/prefer-aggregate-error": "error",
81
136
  "unicorn/prefer-array-find": "error",
82
137
  "unicorn/prefer-array-flat": "error",
83
138
  "unicorn/prefer-array-flat-map": "error",
139
+ "unicorn/prefer-array-from-async": "error",
140
+ "unicorn/prefer-array-from-map": "error",
141
+ "unicorn/prefer-array-from-range": "error",
84
142
  "unicorn/prefer-array-index-of": "error",
143
+ "unicorn/prefer-array-last-methods": "error",
144
+ "unicorn/prefer-array-slice": "error",
85
145
  "unicorn/prefer-array-some": "error",
86
146
  "unicorn/prefer-at": "error",
87
147
  "unicorn/prefer-blob-reading-methods": "error",
88
148
  "unicorn/prefer-code-point": "error",
89
149
  "unicorn/prefer-date-now": "error",
90
150
  "unicorn/prefer-default-parameters": "error",
151
+ "unicorn/prefer-dispose": "error",
91
152
  "unicorn/prefer-dom-node-append": "error",
92
- "unicorn/prefer-dom-node-dataset": "error",
93
153
  "unicorn/prefer-dom-node-remove": "error",
94
154
  "unicorn/prefer-dom-node-text-content": "error",
155
+ "unicorn/prefer-error-is-error": "error",
95
156
  "unicorn/prefer-event-target": "error",
96
- "unicorn/prefer-export-from": ["error", { ignoreUsedVariables: true }],
157
+ "unicorn/prefer-export-from": ["error", { checkUsedVariables: false }],
158
+ "unicorn/prefer-flat-math-min-max": "error",
159
+ "unicorn/prefer-get-or-insert-computed": "error",
160
+ "unicorn/prefer-global-number-constants": "error",
161
+ "unicorn/prefer-group-by": "error",
162
+ "unicorn/prefer-https": "error",
97
163
  "unicorn/prefer-import-meta-properties": "error",
98
164
  "unicorn/prefer-includes": "error",
99
- "unicorn/prefer-json-parse-buffer": "error",
165
+ "unicorn/prefer-iterator-concat": "error",
166
+ "unicorn/prefer-iterator-to-array": "error",
100
167
  "unicorn/prefer-keyboard-event-key": "error",
101
168
  "unicorn/prefer-logical-operator-over-ternary": "error",
169
+ "unicorn/prefer-math-abs": "error",
170
+ "unicorn/prefer-math-constants": "error",
102
171
  "unicorn/prefer-math-min-max": "error",
103
172
  "unicorn/prefer-math-trunc": "error",
104
173
  "unicorn/prefer-modern-dom-apis": "error",
105
174
  "unicorn/prefer-modern-math-apis": "error",
106
175
  "unicorn/prefer-negative-index": "error",
107
176
  "unicorn/prefer-node-protocol": "error",
177
+ "unicorn/prefer-number-coercion": "error",
178
+ "unicorn/prefer-number-is-safe-integer": "error",
108
179
  "unicorn/prefer-number-properties": "error",
109
180
  "unicorn/prefer-object-from-entries": "error",
110
181
  "unicorn/prefer-optional-catch-binding": "error",
182
+ "unicorn/prefer-promise-try": "error",
183
+ "unicorn/prefer-promise-with-resolvers": "error",
111
184
  "unicorn/prefer-prototype-methods": "error",
112
185
  "unicorn/prefer-query-selector": "error",
186
+ "unicorn/prefer-queue-microtask": "error",
113
187
  "unicorn/prefer-reflect-apply": "error",
114
188
  "unicorn/prefer-regexp-test": "error",
115
189
  "unicorn/prefer-response-static-json": "error",
116
190
  "unicorn/prefer-set-has": "error",
117
191
  "unicorn/prefer-set-size": "error",
118
192
  "unicorn/prefer-single-call": "error",
193
+ "unicorn/prefer-string-match-all": "error",
194
+ "unicorn/prefer-string-pad-start-end": "error",
195
+ "unicorn/prefer-string-repeat": "error",
119
196
  "unicorn/prefer-string-replace-all": "error",
120
197
  "unicorn/prefer-string-slice": "error",
121
198
  "unicorn/prefer-string-starts-ends-with": "error",
@@ -125,36 +202,11 @@ export const unicorn = {
125
202
  "unicorn/prefer-ternary": "error",
126
203
  "unicorn/prefer-top-level-await": "error",
127
204
  "unicorn/prefer-type-error": "error",
128
- "unicorn/prevent-abbreviations": [
129
- "error",
130
- {
131
- ignore: [
132
- "utils",
133
- "Utils",
134
- "Arg",
135
- "Args",
136
- "Param",
137
- "Params",
138
- "Prev",
139
- "Prop",
140
- "Props",
141
- "Ref",
142
- "Refs",
143
- "arg",
144
- "args",
145
- "env",
146
- "param",
147
- "params",
148
- "prev",
149
- "prop",
150
- "props",
151
- "ref",
152
- "refs",
153
- ],
154
- },
155
- ],
205
+ "unicorn/prefer-url-can-parse": "error",
206
+ "unicorn/prefer-url-href": "error",
156
207
  "unicorn/relative-url-style": ["error", "always"],
157
208
  "unicorn/require-array-join-separator": "error",
209
+ "unicorn/require-array-sort-compare": "error",
158
210
  "unicorn/require-number-to-fixed-digits-argument": "error",
159
211
  "unicorn/require-post-message-target-origin": "error",
160
212
  "unicorn/switch-case-braces": ["error", "always"],
@@ -63,7 +63,7 @@ export const vitest = {
63
63
  "@vitest/prefer-expect-resolves": "error",
64
64
  "@vitest/prefer-hooks-in-order": "error",
65
65
  "@vitest/prefer-hooks-on-top": "error",
66
- "@vitest/prefer-lowercase-title": "error",
66
+ "@vitest/prefer-lowercase-title": ["error", { ignoreTopLevelDescribe: true }],
67
67
  "@vitest/prefer-mock-promise-shorthand": "error",
68
68
  "@vitest/prefer-mock-return-shorthand": "error",
69
69
  "@vitest/prefer-spy-on": "error",
@@ -12,7 +12,7 @@ import {
12
12
  export const noCommentedOutCode = {
13
13
  create(context) {
14
14
  const sourceCode = context.sourceCode
15
- const parserOptions = { ...context.parserOptions, project: undefined }
15
+ const parserOptions = { ...context.languageOptions.parserOptions, project: undefined }
16
16
 
17
17
  function tryParse(content) {
18
18
  try {
@@ -42,7 +42,7 @@ export function hasLabeledStatementBody(program) {
42
42
  }
43
43
 
44
44
  export function isRegionComment(content) {
45
- return /\s*#(end)?region/.test(content)
45
+ return /^\s*#(end)?region/.test(content)
46
46
  }
47
47
 
48
48
  export function toBlocks(comments) {
@@ -52,7 +52,7 @@ export function toBlocks(comments) {
52
52
  for (const comment of comments) {
53
53
  if (comment.type === "Block") {
54
54
  blocks.push({
55
- content: comment.value.replace(/^\s*\*/, "").replaceAll(/\n\s*\*/g, "\n"),
55
+ content: comment.value.replace(/^[^\S\n]*\*/, "").replaceAll(/\n[^\S\n]*\*/g, "\n"),
56
56
  loc: { ...comment.loc },
57
57
  })
58
58
  prevLine = undefined
@@ -53,12 +53,15 @@ export const noRestrictedDependencies = {
53
53
  return
54
54
  }
55
55
 
56
- for (const dep of node.value.properties) {
57
- if (dep.key.type !== "JSONLiteral" || typeof dep.key.value !== "string") {
56
+ for (const dependency of node.value.properties) {
57
+ if (
58
+ dependency.key.type !== "JSONLiteral" ||
59
+ typeof dependency.key.value !== "string"
60
+ ) {
58
61
  continue
59
62
  }
60
63
 
61
- const packageName = dep.key.value
64
+ const packageName = dependency.key.value
62
65
 
63
66
  for (const pattern of patterns) {
64
67
  if (matchesPattern(packageName, pattern)) {
@@ -69,7 +72,7 @@ export const noRestrictedDependencies = {
69
72
  pattern,
70
73
  },
71
74
  messageId: "restricted",
72
- node: dep.key,
75
+ node: dependency.key,
73
76
  })
74
77
  break
75
78
  }
@@ -0,0 +1,63 @@
1
+ const DEFAULT_DIRECTORIES = ["src/modules", "src/components"]
2
+
3
+ function isInDirectories(filePath, directories) {
4
+ const normalizedPath = filePath.replaceAll("\\", "/")
5
+
6
+ return directories.some((directory) => {
7
+ const normalizedDirectory = directory.replaceAll("\\", "/")
8
+
9
+ return normalizedPath.includes(`${normalizedDirectory}/`)
10
+ })
11
+ }
12
+
13
+ export const noTypesInTsx = {
14
+ create(context) {
15
+ const directories = context.options[0]?.directories ?? DEFAULT_DIRECTORIES
16
+
17
+ if (!context.filename.endsWith(".tsx")) {
18
+ return {}
19
+ }
20
+
21
+ if (!isInDirectories(context.filename, directories)) {
22
+ return {}
23
+ }
24
+
25
+ function report(node) {
26
+ context.report({
27
+ messageId: "noTypesInTsx",
28
+ node,
29
+ })
30
+ }
31
+
32
+ return {
33
+ TSInterfaceDeclaration: report,
34
+ TSTypeAliasDeclaration: report,
35
+ }
36
+ },
37
+ meta: {
38
+ docs: {
39
+ description:
40
+ "Requires type and interface declarations to live in a sibling `.types.ts` file instead of a `.tsx` file.",
41
+ },
42
+ messages: {
43
+ noTypesInTsx:
44
+ "Type declarations are not allowed in `.tsx` files. Move it to a sibling `.types.ts` file.",
45
+ },
46
+ schema: [
47
+ {
48
+ additionalProperties: false,
49
+ properties: {
50
+ directories: {
51
+ default: DEFAULT_DIRECTORIES,
52
+ items: {
53
+ type: "string",
54
+ },
55
+ type: "array",
56
+ },
57
+ },
58
+ type: "object",
59
+ },
60
+ ],
61
+ type: "problem",
62
+ },
63
+ }
@@ -261,11 +261,7 @@ function collectUtilityCallReferences(node, context) {
261
261
  }
262
262
 
263
263
  const callee = node.expression
264
- let functionName = null
265
-
266
- if (ts.isIdentifier(callee)) {
267
- functionName = callee.text
268
- }
264
+ const functionName = ts.isIdentifier(callee) ? callee.text : null
269
265
 
270
266
  if (!functionName || !context.utilityFunctionIdentifiers.has(functionName)) {
271
267
  return
@@ -404,10 +400,18 @@ function resolveDocumentPaths(cssPath, templates) {
404
400
 
405
401
  return templates.map((template) => {
406
402
  return template
407
- .replaceAll("{cssDirectory}", variables.cssDirectory)
408
- .replaceAll("{cssName}", variables.cssName)
409
- .replaceAll("{cssBaseName}", variables.cssBaseName)
410
- .replaceAll("{cssDirectoryName}", variables.cssDirectoryName)
403
+ .replaceAll("{cssDirectory}", () => {
404
+ return variables.cssDirectory
405
+ })
406
+ .replaceAll("{cssName}", () => {
407
+ return variables.cssName
408
+ })
409
+ .replaceAll("{cssBaseName}", () => {
410
+ return variables.cssBaseName
411
+ })
412
+ .replaceAll("{cssDirectoryName}", () => {
413
+ return variables.cssDirectoryName
414
+ })
411
415
  })
412
416
  }
413
417